Fix various panics and miscompilations

This commit is contained in:
Jef
2019-04-24 15:00:15 +02:00
parent 745d9ae162
commit 21cdd55cd2
2 changed files with 35 additions and 25 deletions

View File

@@ -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,21 +2020,19 @@ 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..] {
if *elem == old_loc {
*elem = new_loc;
self.block_state.regs.release(reg); 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); self.block_state.regs.release(trash);
false
} else {
true
} }
} else { } else {
false
}
} 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

View File

@@ -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());