mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 20:28:02 +00:00
fix Num.shift_right_by to not mutate src register
The intent of this change is to fix a bug calling `Num.shift_right_by(a, b)` mutates `a`. This was happening in the dev backend only, and the cause was some generated assembly which writes to register a is stored in.
This commit is contained in:
parent
2331aa1d77
commit
c195cff8e3
1 changed files with 21 additions and 40 deletions
|
@ -4561,46 +4561,27 @@ impl<
|
|||
// be for our particular integer width
|
||||
let sign_extend_shift_amount = 64 - (int_width.stack_size() as i64 * 8);
|
||||
|
||||
if sign_extend_shift_amount > 0 {
|
||||
self.storage_manager.with_tmp_general_reg(
|
||||
buf,
|
||||
|storage_manager, buf, tmp_reg| {
|
||||
ASM::mov_reg64_imm64(buf, tmp_reg, sign_extend_shift_amount);
|
||||
ASM::shl_reg64_reg64_reg64(
|
||||
buf,
|
||||
storage_manager,
|
||||
src1_reg,
|
||||
src1_reg,
|
||||
tmp_reg,
|
||||
);
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
ASM::sar_reg64_reg64_reg64(
|
||||
buf,
|
||||
&mut self.storage_manager,
|
||||
dst_reg,
|
||||
src1_reg,
|
||||
src2_reg,
|
||||
);
|
||||
|
||||
if sign_extend_shift_amount > 0 {
|
||||
// shift back if needed
|
||||
self.storage_manager.with_tmp_general_reg(
|
||||
&mut self.buf,
|
||||
|storage_manager, buf, tmp_reg| {
|
||||
ASM::mov_reg64_imm64(buf, tmp_reg, sign_extend_shift_amount);
|
||||
ASM::shr_reg64_reg64_reg64(
|
||||
buf,
|
||||
storage_manager,
|
||||
dst_reg,
|
||||
dst_reg,
|
||||
tmp_reg,
|
||||
);
|
||||
},
|
||||
)
|
||||
}
|
||||
// PERF: could just be one shr for unsigned ints cases
|
||||
// PERF: the shl/shr can be skipped when sign_extend_shift_amount is 0
|
||||
self.storage_manager
|
||||
.with_tmp_general_reg(buf, |storage_manager, buf, tmp_reg| {
|
||||
ASM::mov_reg64_imm64(buf, tmp_reg, sign_extend_shift_amount);
|
||||
ASM::shl_reg64_reg64_reg64(
|
||||
buf,
|
||||
storage_manager,
|
||||
dst_reg,
|
||||
src1_reg,
|
||||
tmp_reg,
|
||||
);
|
||||
ASM::sar_reg64_reg64_reg64(
|
||||
buf,
|
||||
storage_manager,
|
||||
dst_reg,
|
||||
dst_reg,
|
||||
src2_reg,
|
||||
);
|
||||
ASM::shr_reg64_reg64_reg64(buf, storage_manager, dst_reg, dst_reg, tmp_reg);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue