fix fallthrough in cond branches

pull/21/head
Ondřej Hruška 4 years ago
parent a867f43763
commit a52f1e5e72
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 17
      csn_asm/src/instr/mod.rs
  2. 9
      csn_asm/src/lib.rs

@ -32,21 +32,30 @@ impl Flatten for Instr {
if let Some(branches) = self.branches { if let Some(branches) = self.branches {
let labels = HashMap::<Cond, u32>::new(); let labels = HashMap::<Cond, u32>::new();
let _branch_count = branches.len(); let branch_count = branches.len();
for (_cnt, (cond, branch)) in branches.into_iter().enumerate() { let end_lbl = Label::unique(label_num);
for (cnt, (cond, branch)) in branches.into_iter().enumerate() {
if labels.contains_key(&cond) { if labels.contains_key(&cond) {
return Err(Error::Asm(AsmError::ConditionalAlreadyUsed(cond))); return Err(Error::Asm(AsmError::ConditionalAlreadyUsed(cond)));
} }
let next_lbl = Label::unique(label_num); let next_lbl = if cnt == branch_count - 1 {
end_lbl.clone()
} else {
Label::unique(label_num)
};
ops.push(Op::JumpIf(!cond, next_lbl.clone())); ops.push(Op::JumpIf(!cond, next_lbl.clone()));
for branch_instr in branch { for branch_instr in branch {
ops.extend(branch_instr.flatten(label_num)?); ops.extend(branch_instr.flatten(label_num)?);
} }
ops.push(Op::Label(next_lbl)); if cnt != branch_count - 1 {
ops.push(Op::Jump(end_lbl.clone()));
ops.push(Op::Label(next_lbl));
}
} }
ops.push(Op::Label(end_lbl));
} }
Ok(ops) Ok(ops)

@ -233,7 +233,7 @@ mod tests {
Rd::new(SrcDisp::Register(Register::Gen(0))), Rd::new(SrcDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(1))), Rd::new(SrcDisp::Register(Register::Gen(1))),
), ),
Op::JumpIf(Cond::NotEqual, Label::Numbered(0)), Op::JumpIf(Cond::NotEqual, Label::Numbered(1)),
Op::Mov( Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(0))), Wr::new(DstDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(0))), Rd::new(SrcDisp::Register(Register::Gen(0))),
@ -242,8 +242,9 @@ mod tests {
Wr::new(DstDisp::Register(Register::Gen(1))), Wr::new(DstDisp::Register(Register::Gen(1))),
Rd::new(SrcDisp::Register(Register::Gen(2))), Rd::new(SrcDisp::Register(Register::Gen(2))),
), ),
Op::Label(Label::Numbered(0)), Op::Jump(Label::Numbered(0)),
Op::JumpIf(Cond::LessOrEqual, Label::Numbered(1)), Op::Label(Label::Numbered(1)),
Op::JumpIf(Cond::LessOrEqual, Label::Numbered(0)),
Op::Mov( Op::Mov(
Wr::new(DstDisp::Register(Register::Gen(0))), Wr::new(DstDisp::Register(Register::Gen(0))),
Rd::new(SrcDisp::Register(Register::Gen(0))), Rd::new(SrcDisp::Register(Register::Gen(0))),
@ -252,7 +253,7 @@ mod tests {
Wr::new(DstDisp::Register(Register::Gen(1))), Wr::new(DstDisp::Register(Register::Gen(1))),
Rd::new(SrcDisp::Register(Register::Gen(1))), Rd::new(SrcDisp::Register(Register::Gen(1))),
), ),
Op::Label(Label::Numbered(1)), Op::Label(Label::Numbered(0)),
], parsed); ], parsed);
} }
} }

Loading…
Cancel
Save