aarch64: Implement lowering brz,brnz for i128 values

This commit is contained in:
Afonso Bordado
2021-06-18 00:19:49 +01:00
parent fb07ff5740
commit a26be628bc
3 changed files with 86 additions and 31 deletions

View File

@@ -3515,6 +3515,7 @@ pub(crate) fn lower_branch<C: LowerCtx<I = Inst>>(
match op0 { match op0 {
Opcode::Brz | Opcode::Brnz => { Opcode::Brz | Opcode::Brnz => {
let ty = ctx.input_ty(branches[0], 0);
let flag_input = InsnInput { let flag_input = InsnInput {
insn: branches[0], insn: branches[0],
input: 0, input: 0,
@@ -3549,14 +3550,19 @@ pub(crate) fn lower_branch<C: LowerCtx<I = Inst>>(
kind: CondBrKind::Cond(cond), kind: CondBrKind::Cond(cond),
}); });
} else { } else {
let rt = put_input_in_reg( let rt = if ty == I128 {
ctx, let tmp = ctx.alloc_tmp(I64).only_reg().unwrap();
InsnInput { let input = put_input_in_regs(ctx, flag_input);
insn: branches[0], ctx.emit(Inst::AluRRR {
input: 0, alu_op: ALUOp::Orr64,
}, rd: tmp,
NarrowValueMode::ZeroExtend64, rn: input.regs()[0],
); rm: input.regs()[1],
});
tmp.to_reg()
} else {
put_input_in_reg(ctx, flag_input, NarrowValueMode::ZeroExtend64)
};
let kind = match op0 { let kind = match op0 {
Opcode::Brz => CondBrKind::Zero(rt), Opcode::Brz => CondBrKind::Zero(rt),
Opcode::Brnz => CondBrKind::NotZero(rt), Opcode::Brnz => CondBrKind::NotZero(rt),

View File

@@ -253,3 +253,49 @@ block1:
; check: movz x0, #1 ; check: movz x0, #1
; nextln: ldp fp, lr, [sp], #16 ; nextln: ldp fp, lr, [sp], #16
; nextln: ret ; nextln: ret
function %i128_brz(i128){
block0(v0: i128):
brz v0, block1
jump block1
block1:
nop
return
}
; check: stp fp, lr, [sp, #-16]!
; nextln: mov fp, sp
; nextln: orr x0, x0, x1
; nextln: cbz x0, label1 ; b label2
; check: Block 1:
; check: b label3
; check: Block 2:
; check: b label3
; check: Block 3:
; check: ldp fp, lr, [sp], #16
; nextln: ret
function %i128_brnz(i128){
block0(v0: i128):
brnz v0, block1
jump block1
block1:
nop
return
}
; check: stp fp, lr, [sp, #-16]!
; nextln: mov fp, sp
; nextln: orr x0, x0, x1
; nextln: cbnz x0, label1 ; b label2
; check: Block 1:
; check: b label3
; check: Block 2:
; check: b label3
; check: Block 3:
; check: ldp fp, lr, [sp], #16
; nextln: ret

View File

@@ -1,42 +1,45 @@
test run test run
; target aarch64 TODO: Not yet implemented on aarch64 target aarch64
; target s390x TODO: Not yet implemented on s390x ; target s390x TODO: Not yet implemented on s390x
target x86_64 machinst target x86_64 machinst
target x86_64 legacy target x86_64 legacy
function %br_false() -> b1 { function %i128_br(i64, i64) -> b1 {
block0: block0(v0: i64, v1: i64):
v10 = iconst.i64 0x42 v2 = iconcat v0, v1
v11 = iconst.i64 0x00 brz v2, block2
v0 = iconcat v10, v11
brz v0, block2
jump block1 jump block1
block1: block1:
v1 = bconst.b1 true v3 = bconst.b1 true
return v1 return v3
block2: block2:
v2 = bconst.b1 false v4 = bconst.b1 false
return v2 return v4
} }
; run ; run: %i128_br(0, 0) == false
; run: %i128_br(-1, 0) == true
; run: %i128_br(0, -1) == true
; run: %i128_br(-1, -1) == true
function %br_true() -> b1 {
block0: function %i128_brnz(i64, i64) -> b1 {
v10 = iconst.i64 0x00 block0(v0: i64, v1: i64):
v11 = iconst.i64 0x00 v2 = iconcat v0, v1
v0 = iconcat v10, v11 brnz v2, block2
brz v0, block2
jump block1 jump block1
block1: block1:
v1 = bconst.b1 false v3 = bconst.b1 true
return v1 return v3
block2: block2:
v2 = bconst.b1 true v4 = bconst.b1 false
return v2 return v4
} }
; run ; run: %i128_brnz(0, 0) == true
; run: %i128_brnz(-1, 0) == false
; run: %i128_brnz(0, -1) == false
; run: %i128_brnz(-1, -1) == false