Fix various panics and miscompilations
This commit is contained in:
@@ -632,9 +632,9 @@ impl TranslatedCodeSection {
|
|||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct BlockState {
|
pub struct BlockState {
|
||||||
stack: Stack,
|
pub stack: Stack,
|
||||||
depth: StackDepth,
|
pub depth: StackDepth,
|
||||||
regs: Registers,
|
pub regs: Registers,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Stack = Vec<ValueLocation>;
|
type Stack = Vec<ValueLocation>;
|
||||||
@@ -992,7 +992,7 @@ macro_rules! shift {
|
|||||||
let mut count = self.pop();
|
let mut count = self.pop();
|
||||||
let mut val = self.pop();
|
let mut val = self.pop();
|
||||||
|
|
||||||
if let Some(imm) = val.immediate() {
|
if let Some(imm) = count.immediate() {
|
||||||
if let Some(imm) = imm.as_int() {
|
if let Some(imm) = imm.as_int() {
|
||||||
if let Ok(imm) = i8::try_from(imm) {
|
if let Ok(imm) = i8::try_from(imm) {
|
||||||
let reg = self.into_temp_reg($ty, val).unwrap();
|
let reg = self.into_temp_reg($ty, val).unwrap();
|
||||||
@@ -1000,6 +1000,8 @@ macro_rules! shift {
|
|||||||
dynasm!(self.asm
|
dynasm!(self.asm
|
||||||
; $instr $reg_ty(reg.rq().unwrap()), imm
|
; $instr $reg_ty(reg.rq().unwrap()), imm
|
||||||
);
|
);
|
||||||
|
self.push(ValueLocation::Reg(reg));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2018,20 +2020,18 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
let old_loc = self.block_state.stack[pos];
|
let old_loc = self.block_state.stack[pos];
|
||||||
|
|
||||||
let new_loc = self.push_physical(old_loc);
|
let new_loc = self.push_physical(old_loc);
|
||||||
|
self.block_state.stack[pos] = new_loc;
|
||||||
for elem in &mut self.block_state.stack[pos..] {
|
|
||||||
if *elem == old_loc {
|
|
||||||
*elem = new_loc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let reg = old_loc.reg().unwrap();
|
let reg = old_loc.reg().unwrap();
|
||||||
|
|
||||||
while self.block_state.regs.num_usages(reg) > 0 {
|
for elem in &mut self.block_state.stack[pos + 1..] {
|
||||||
self.block_state.regs.release(reg);
|
if *elem == old_loc {
|
||||||
|
*elem = new_loc;
|
||||||
|
self.block_state.regs.release(reg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
@@ -2375,23 +2375,36 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
fn set_stack_depth(&mut self, depth: StackDepth) {
|
fn set_stack_depth(&mut self, depth: StackDepth) {
|
||||||
if self.block_state.depth.0 != depth.0 {
|
if self.block_state.depth.0 != depth.0 {
|
||||||
let diff = depth.0 as i32 - self.block_state.depth.0 as i32;
|
let diff = depth.0 as i32 - self.block_state.depth.0 as i32;
|
||||||
if diff.abs() == 1 {
|
let emit_lea = if diff.abs() == 1 {
|
||||||
if self.block_state.depth.0 < depth.0 {
|
if self.block_state.depth.0 < depth.0 {
|
||||||
for _ in 0..depth.0 - self.block_state.depth.0 {
|
for _ in 0..depth.0 - self.block_state.depth.0 {
|
||||||
dynasm!(self.asm
|
dynasm!(self.asm
|
||||||
; push rax
|
; push rax
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
false
|
||||||
} else if self.block_state.depth.0 > depth.0 {
|
} else if self.block_state.depth.0 > depth.0 {
|
||||||
let trash = self.take_reg(I64).unwrap();
|
if let Some(trash) = self.take_reg(I64) {
|
||||||
for _ in 0..self.block_state.depth.0 - depth.0 {
|
for _ in 0..self.block_state.depth.0 - depth.0 {
|
||||||
dynasm!(self.asm
|
dynasm!(self.asm
|
||||||
; pop Rq(trash.rq().unwrap())
|
; pop Rq(trash.rq().unwrap())
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
self.block_state.regs.release(trash);
|
||||||
|
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
}
|
}
|
||||||
self.block_state.regs.release(trash);
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
|
||||||
|
if emit_lea {
|
||||||
dynasm!(self.asm
|
dynasm!(self.asm
|
||||||
; lea rsp, [rsp + (self.block_state.depth.0 as i32 - depth.0 as i32) * WORD_SIZE as i32]
|
; lea rsp, [rsp + (self.block_state.depth.0 as i32 - depth.0 as i32) * WORD_SIZE as i32]
|
||||||
);
|
);
|
||||||
@@ -4800,7 +4813,6 @@ impl<'this, M: ModuleContext> Context<'this, M> {
|
|||||||
|
|
||||||
if offset == -(WORD_SIZE as i32) {
|
if offset == -(WORD_SIZE as i32) {
|
||||||
self.push_physical(val);
|
self.push_physical(val);
|
||||||
self.free_value(val);
|
|
||||||
} else {
|
} else {
|
||||||
let gpr = self.into_reg(GPRType::Rq, val).unwrap();
|
let gpr = self.into_reg(GPRType::Rq, val).unwrap();
|
||||||
dynasm!(self.asm
|
dynasm!(self.asm
|
||||||
|
|||||||
@@ -139,12 +139,10 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
while let Some(op) = body.next() {
|
while let Some(op) = body.next() {
|
||||||
println!("{}", op);
|
|
||||||
|
|
||||||
if let Some(Operator::Label(label)) = body.peek() {
|
if let Some(Operator::Label(label)) = body.peek() {
|
||||||
let block = blocks
|
let block = blocks
|
||||||
.get_mut(&BrTarget::Label(label.clone()))
|
.get_mut(&BrTarget::Label(label.clone()))
|
||||||
.unwrap_or_else(|| panic!("Label defined before being declared"));
|
.expect("Label defined before being declared");
|
||||||
block.is_next = true;
|
block.is_next = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +211,7 @@ where
|
|||||||
Some(Right(virt)) => {
|
Some(Right(virt)) => {
|
||||||
ctx.set_state(virt.clone());
|
ctx.set_state(virt.clone());
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => assert_eq!(block.params as usize, ctx.block_state.stack.len()),
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.define_label(block.label.label().unwrap().clone());
|
ctx.define_label(block.label.label().unwrap().clone());
|
||||||
|
|||||||
Reference in New Issue
Block a user