mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
fix register not cleared before reading bool
This commit is contained in:
parent
cb5241380f
commit
2eaf158053
5 changed files with 93 additions and 51 deletions
|
@ -965,33 +965,32 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn movsx_reg64_base32(buf: &mut Vec<'_, u8>, dst: AArch64GeneralReg, offset: i32, size: u8) {
|
||||
debug_assert!(size <= 8);
|
||||
if size == 8 {
|
||||
Self::mov_reg64_base32(buf, dst, offset);
|
||||
} else if size == 4 {
|
||||
todo!("sign extending 4 byte values");
|
||||
} else if size == 2 {
|
||||
todo!("sign extending 2 byte values");
|
||||
} else if size == 1 {
|
||||
todo!("sign extending 1 byte values");
|
||||
} else {
|
||||
internal_error!("Invalid size for sign extension: {}", size);
|
||||
fn movsx_reg_base32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
register_width: RegisterWidth,
|
||||
dst: AArch64GeneralReg,
|
||||
offset: i32,
|
||||
) {
|
||||
match register_width {
|
||||
RegisterWidth::W8 => todo!("sign extend 1 byte values"),
|
||||
RegisterWidth::W16 => todo!("sign extend 2 byte values"),
|
||||
RegisterWidth::W32 => todo!("sign extend 4 byte values"),
|
||||
RegisterWidth::W64 => Self::mov_reg64_base32(buf, dst, offset),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn movzx_reg64_base32(buf: &mut Vec<'_, u8>, dst: AArch64GeneralReg, offset: i32, size: u8) {
|
||||
debug_assert!(size <= 8);
|
||||
if size == 8 {
|
||||
Self::mov_reg64_base32(buf, dst, offset);
|
||||
} else if size == 4 {
|
||||
todo!("zero extending 4 byte values");
|
||||
} else if size == 2 {
|
||||
todo!("zero extending 2 byte values");
|
||||
} else if size == 1 {
|
||||
todo!("zero extending 1 byte values");
|
||||
} else {
|
||||
internal_error!("Invalid size for zero extension: {}", size);
|
||||
fn movzx_reg_base32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
register_width: RegisterWidth,
|
||||
dst: AArch64GeneralReg,
|
||||
offset: i32,
|
||||
) {
|
||||
match register_width {
|
||||
RegisterWidth::W8 => todo!("zero extend 1 byte values"),
|
||||
RegisterWidth::W16 => todo!("zero extend 2 byte values"),
|
||||
RegisterWidth::W32 => todo!("zero extend 4 byte values"),
|
||||
RegisterWidth::W64 => Self::mov_reg64_base32(buf, dst, offset),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -391,10 +391,19 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
|||
|
||||
/// Sign extends the data at `offset` with `size` as it copies it to `dst`
|
||||
/// size must be less than or equal to 8.
|
||||
fn movsx_reg64_base32(buf: &mut Vec<'_, u8>, dst: GeneralReg, offset: i32, size: u8);
|
||||
/// Zero extends the data at `offset` with `size` as it copies it to `dst`
|
||||
/// size must be less than or equal to 8.
|
||||
fn movzx_reg64_base32(buf: &mut Vec<'_, u8>, dst: GeneralReg, offset: i32, size: u8);
|
||||
fn movsx_reg_base32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
register_width: RegisterWidth,
|
||||
dst: GeneralReg,
|
||||
offset: i32,
|
||||
);
|
||||
|
||||
fn movzx_reg_base32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
register_width: RegisterWidth,
|
||||
dst: GeneralReg,
|
||||
offset: i32,
|
||||
);
|
||||
|
||||
fn mov_freg64_stack32(buf: &mut Vec<'_, u8>, dst: FloatReg, offset: i32);
|
||||
fn mov_reg64_stack32(buf: &mut Vec<'_, u8>, dst: GeneralReg, offset: i32);
|
||||
|
@ -4075,10 +4084,12 @@ impl<
|
|||
}
|
||||
IntWidth::I16 | IntWidth::U16 => {
|
||||
let dst_reg = storage_manager.claim_general_reg(buf, &dst);
|
||||
ASM::xor_reg64_reg64_reg64(buf, dst_reg, dst_reg, dst_reg);
|
||||
ASM::mov_reg16_mem16_offset32(buf, dst_reg, ptr_reg, offset);
|
||||
}
|
||||
IntWidth::I8 | IntWidth::U8 => {
|
||||
let dst_reg = storage_manager.claim_general_reg(buf, &dst);
|
||||
ASM::xor_reg64_reg64_reg64(buf, dst_reg, dst_reg, dst_reg);
|
||||
ASM::mov_reg8_mem8_offset32(buf, dst_reg, ptr_reg, offset);
|
||||
}
|
||||
},
|
||||
|
@ -4093,6 +4104,8 @@ impl<
|
|||
Builtin::Bool => {
|
||||
// the same as an 8-bit integer
|
||||
let dst_reg = storage_manager.claim_general_reg(buf, &dst);
|
||||
|
||||
ASM::xor_reg64_reg64_reg64(buf, dst_reg, dst_reg, dst_reg);
|
||||
ASM::mov_reg8_mem8_offset32(buf, dst_reg, ptr_reg, offset);
|
||||
}
|
||||
Builtin::Decimal => {
|
||||
|
|
|
@ -23,6 +23,8 @@ use RegStorage::*;
|
|||
use StackStorage::*;
|
||||
use Storage::*;
|
||||
|
||||
use super::RegisterWidth;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum RegStorage<GeneralReg: RegTrait, FloatReg: RegTrait> {
|
||||
General(GeneralReg),
|
||||
|
@ -343,10 +345,19 @@ impl<
|
|||
sign_extend,
|
||||
}) => {
|
||||
let reg = self.get_general_reg(buf);
|
||||
|
||||
let register_width = match size {
|
||||
8 => RegisterWidth::W64,
|
||||
4 => RegisterWidth::W32,
|
||||
2 => RegisterWidth::W16,
|
||||
1 => RegisterWidth::W8,
|
||||
_ => internal_error!("Invalid size: {size}"),
|
||||
};
|
||||
|
||||
if sign_extend {
|
||||
ASM::movsx_reg64_base32(buf, reg, base_offset, size as u8);
|
||||
ASM::movsx_reg_base32(buf, register_width, reg, base_offset);
|
||||
} else {
|
||||
ASM::movzx_reg64_base32(buf, reg, base_offset, size as u8);
|
||||
ASM::movzx_reg_base32(buf, register_width, reg, base_offset);
|
||||
}
|
||||
self.general_used_regs.push((reg, *sym));
|
||||
self.symbol_storage_map.insert(*sym, Reg(General(reg)));
|
||||
|
@ -469,10 +480,18 @@ impl<
|
|||
}) => {
|
||||
debug_assert!(*size <= 8);
|
||||
|
||||
let register_width = match size {
|
||||
8 => RegisterWidth::W64,
|
||||
4 => RegisterWidth::W32,
|
||||
2 => RegisterWidth::W16,
|
||||
1 => RegisterWidth::W8,
|
||||
_ => internal_error!("Invalid size: {size}"),
|
||||
};
|
||||
|
||||
if *sign_extend {
|
||||
ASM::movsx_reg64_base32(buf, reg, *base_offset, *size as u8)
|
||||
ASM::movsx_reg_base32(buf, register_width, reg, *base_offset)
|
||||
} else {
|
||||
ASM::movzx_reg64_base32(buf, reg, *base_offset, *size as u8)
|
||||
ASM::movzx_reg_base32(buf, register_width, reg, *base_offset)
|
||||
}
|
||||
}
|
||||
Stack(Complex { size, .. }) => {
|
||||
|
|
|
@ -1687,29 +1687,39 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn movsx_reg64_base32(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, offset: i32, size: u8) {
|
||||
debug_assert!(size <= 8);
|
||||
match size {
|
||||
8 => Self::mov_reg64_base32(buf, dst, offset),
|
||||
4 => movsx_reg64_base32_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
2 => movsx_reg64_base16_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
1 => movsx_reg64_base8_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
_ => internal_error!("Invalid size for sign extension: {size}"),
|
||||
fn movsx_reg_base32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
register_width: RegisterWidth,
|
||||
dst: X86_64GeneralReg,
|
||||
offset: i32,
|
||||
) {
|
||||
use RegisterWidth::*;
|
||||
|
||||
match register_width {
|
||||
W64 => Self::mov_reg64_base32(buf, dst, offset),
|
||||
W32 => movsx_reg64_base32_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
W16 => movsx_reg64_base16_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
W8 => movsx_reg64_base8_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn movzx_reg64_base32(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, offset: i32, size: u8) {
|
||||
debug_assert!(size <= 8);
|
||||
match size {
|
||||
8 => Self::mov_reg64_base32(buf, dst, offset),
|
||||
4 => {
|
||||
fn movzx_reg_base32(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
register_width: RegisterWidth,
|
||||
dst: X86_64GeneralReg,
|
||||
offset: i32,
|
||||
) {
|
||||
use RegisterWidth::*;
|
||||
|
||||
match register_width {
|
||||
W64 => Self::mov_reg64_base32(buf, dst, offset),
|
||||
W32 => {
|
||||
// The Intel documentation (3.4.1.1 General-Purpose Registers in 64-Bit Mode in manual Basic Architecture))
|
||||
// 32-bit operands generate a 32-bit result, zero-extended to a 64-bit result in the destination general-purpose register.
|
||||
Self::mov_reg64_base32(buf, dst, offset)
|
||||
}
|
||||
2 => movzx_reg64_base16_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
1 => movzx_reg64_base8_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
_ => internal_error!("Invalid size for zero extension: {size}"),
|
||||
W16 => movzx_reg64_base16_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
W8 => movzx_reg64_base8_offset32(buf, dst, X86_64GeneralReg::RBP, offset),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue