Fix shift's incorrect register freeing logic

This commit is contained in:
Jef
2019-04-17 16:06:51 +02:00
parent 82e810c8d2
commit a2ef962ed7

View File

@@ -9,6 +9,7 @@ use either::Either;
use std::{
any::{Any, TypeId},
collections::HashMap,
convert::TryFrom,
iter::{self, FromIterator},
mem,
ops::RangeInclusive,
@@ -931,8 +932,23 @@ macro_rules! shift {
let mut count = self.pop();
let mut val = self.pop();
if let Some(imm) = val.immediate() {
if let Some(imm) = imm.as_int() {
if let Ok(imm) = i8::try_from(imm) {
let reg = self.into_temp_reg($ty, val).unwrap();
dynasm!(self.asm
; $instr $reg_ty(reg.rq().unwrap()), imm
);
}
}
}
if val == ValueLocation::Reg(RCX) {
val = ValueLocation::Reg(self.into_temp_reg($ty, val).unwrap());
let new = self.take_reg($ty).unwrap();
self.copy_value(val, CCLoc::Reg(new));
self.free_value(val);
val = ValueLocation::Reg(new);
}
// TODO: Maybe allocate `RCX`, write `count` to it and then free `count`.
@@ -979,7 +995,7 @@ macro_rules! shift {
self.block_state.regs.mark_used(RCX);
count = ValueLocation::Reg(RCX);
let reg = self.into_reg($ty, val).unwrap();
let reg = self.into_temp_reg($ty, val).unwrap();
dynasm!(self.asm
; $instr $reg_ty(reg.rq().unwrap()), cl