adding pointer arithmetic test
This commit is contained in:
parent
7cca9a3683
commit
9ccf91d072
|
@ -30,6 +30,10 @@ main := fn(): int {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if *(&pixel.color.r + 1) != 0 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return pixel.point.x + pixel.point.y + pixel.color.r
|
return pixel.point.x + pixel.point.y + pixel.color.r
|
||||||
+ pixel.color.g + pixel.color.b + pixel.color.a;
|
+ pixel.color.g + pixel.color.b + pixel.color.a;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,10 @@ pub mod bt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_pointer(ty: Type) -> bool {
|
||||||
|
matches!(TypeKind::from_ty(ty), TypeKind::Pointer(_))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn try_upcast(a: Type, b: Type) -> Option<Type> {
|
pub fn try_upcast(a: Type, b: Type) -> Option<Type> {
|
||||||
Some(match (strip_pointer(a.min(b)), strip_pointer(a.max(b))) {
|
Some(match (strip_pointer(a.min(b)), strip_pointer(a.max(b))) {
|
||||||
_ if a == b => a,
|
_ if a == b => a,
|
||||||
|
@ -959,7 +963,28 @@ impl<'a> Codegen<'a> {
|
||||||
let size = self.size_of(ty);
|
let size = self.size_of(ty);
|
||||||
|
|
||||||
let signed = bt::is_signed(ty);
|
let signed = bt::is_signed(ty);
|
||||||
let index = size.ilog2() as usize;
|
|
||||||
|
let min_size = lsize.min(rsize);
|
||||||
|
if bt::is_signed(ty) && min_size < size {
|
||||||
|
let operand = if lsize < rsize { lhs.0 } else { rhs.0 };
|
||||||
|
let op = [i::sxt8, i::sxt16, i::sxt32][min_size.ilog2() as usize];
|
||||||
|
self.code.encode(op(operand, operand));
|
||||||
|
}
|
||||||
|
|
||||||
|
if bt::is_pointer(left.ty) ^ bt::is_pointer(right.ty) {
|
||||||
|
let (offset, ty) = if bt::is_pointer(left.ty) {
|
||||||
|
(lhs.0, left.ty)
|
||||||
|
} else {
|
||||||
|
(rhs.0, right.ty)
|
||||||
|
};
|
||||||
|
|
||||||
|
let TypeKind::Pointer(ty) = TypeKind::from_ty(ty) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let size = self.size_of(self.pointers[ty as usize]);
|
||||||
|
self.code.encode(i::mul64(offset, offset, size as _));
|
||||||
|
}
|
||||||
|
|
||||||
let ops = match op {
|
let ops = match op {
|
||||||
T::Plus => [i::add8, i::add16, i::add32, i::add64],
|
T::Plus => [i::add8, i::add16, i::add32, i::add64],
|
||||||
|
@ -977,8 +1002,13 @@ impl<'a> Codegen<'a> {
|
||||||
|a, b, c| i::diru32(a, ZERO, b, c),
|
|a, b, c| i::diru32(a, ZERO, b, c),
|
||||||
|a, b, c| i::diru64(a, ZERO, b, c),
|
|a, b, c| i::diru64(a, ZERO, b, c),
|
||||||
],
|
],
|
||||||
T::Le | T::Ge => {
|
T::Le | T::Ge | T::Ne => {
|
||||||
let against = if op == T::Le { 1 } else { (-1i64) as _ };
|
let against = match op {
|
||||||
|
T::Le => 1,
|
||||||
|
T::Ne => 0,
|
||||||
|
T::Ge => (-1i64) as _,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
let op = if signed { i::cmps } else { i::cmpu };
|
let op = if signed { i::cmps } else { i::cmpu };
|
||||||
self.code.encode(op(lhs.0, lhs.0, rhs.0));
|
self.code.encode(op(lhs.0, lhs.0, rhs.0));
|
||||||
self.gpa.free(rhs);
|
self.gpa.free(rhs);
|
||||||
|
@ -1008,15 +1038,10 @@ impl<'a> Codegen<'a> {
|
||||||
_ => unimplemented!("{:#?}", op),
|
_ => unimplemented!("{:#?}", op),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.code.encode(ops[index](lhs.0, lhs.0, rhs.0));
|
self.code
|
||||||
|
.encode(ops[size.ilog2() as usize](lhs.0, lhs.0, rhs.0));
|
||||||
self.gpa.free(rhs);
|
self.gpa.free(rhs);
|
||||||
|
|
||||||
let min_size = lsize.min(rsize);
|
|
||||||
if bt::is_signed(ty) && min_size < size {
|
|
||||||
let op = [i::sxt8, i::sxt16, i::sxt32][min_size.ilog2() as usize];
|
|
||||||
self.code.encode(op(lhs.0, lhs.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(Value {
|
Some(Value {
|
||||||
ty,
|
ty,
|
||||||
loc: Loc::Reg(lhs),
|
loc: Loc::Reg(lhs),
|
||||||
|
|
|
@ -113,6 +113,7 @@ gen_token_kind! {
|
||||||
Lt = "<",
|
Lt = "<",
|
||||||
Gt = ">",
|
Gt = ">",
|
||||||
Eq = "==",
|
Eq = "==",
|
||||||
|
Ne = "!=",
|
||||||
#[prec = 22]
|
#[prec = 22]
|
||||||
Amp = "&",
|
Amp = "&",
|
||||||
#[prec = 23]
|
#[prec = 23]
|
||||||
|
@ -216,6 +217,7 @@ impl<'a> Iterator for Lexer<'a> {
|
||||||
b'.' if self.advance_if(b'{') => T::Ctor,
|
b'.' if self.advance_if(b'{') => T::Ctor,
|
||||||
b'.' => T::Dot,
|
b'.' => T::Dot,
|
||||||
b';' => T::Semi,
|
b';' => T::Semi,
|
||||||
|
b'!' if self.advance_if(b'=') => T::Ne,
|
||||||
b'=' if self.advance_if(b'=') => T::Eq,
|
b'=' if self.advance_if(b'=') => T::Eq,
|
||||||
b'=' => T::Assign,
|
b'=' => T::Assign,
|
||||||
b'<' if self.advance_if(b'=') => T::Le,
|
b'<' if self.advance_if(b'=') => T::Le,
|
||||||
|
|
Loading…
Reference in a new issue