arm32 codegen
This commit adds arm32 code generation for some IR insts. Floating-point instructions are not supported, because regalloc does not allow to represent overlapping register classes, which are needed by VFP/Neon. There is also no support for big-endianness, I64 and I128 types.
This commit is contained in:
269
cranelift/filetests/filetests/vcode/arm32/aluops.clif
Normal file
269
cranelift/filetests/filetests/vcode/arm32/aluops.clif
Normal file
@@ -0,0 +1,269 @@
|
||||
test compile
|
||||
target arm
|
||||
|
||||
function %iadd(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
v2 = iadd v0, v1
|
||||
return v2
|
||||
}
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: add r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %iadd(i16, i16) -> i16 {
|
||||
block0(v0: i16, v1: i16):
|
||||
v2 = iadd v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: add r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %iadd(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = iadd v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: add r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %sadd_sat(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = sadd_sat v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: qadd r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %isub(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = isub v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: sub r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ssub_sat(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = ssub_sat v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: qsub r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ineg(i32) -> i32 {
|
||||
block0(v0: i32):
|
||||
v1 = ineg v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: rsb r0, r0, #0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %imul(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = imul v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mul r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %umulhi(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = umulhi v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: umull r1, r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %smulhi(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = smulhi v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: smull r1, r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %udiv(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = udiv v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: udiv r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %sdiv(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = sdiv v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: sdiv r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %iadd_flags(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2, v3 = iadd_ifcout v0, v1
|
||||
v4, v5 = iadd_ifcarry v1, v2, v3
|
||||
v6 = iadd_ifcin v1, v4, v5
|
||||
return v6
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: adds r0, r0, r1
|
||||
; nextln: adcs r0, r1, r0
|
||||
; nextln: adc r0, r1, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %isub_flags(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2, v3 = isub_ifbout v0, v1
|
||||
v4, v5 = isub_ifborrow v1, v2, v3
|
||||
v6 = isub_ifbin v1, v4, v5
|
||||
return v6
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: subs r0, r0, r1
|
||||
; nextln: sbcs r0, r1, r0
|
||||
; nextln: sbc r0, r1, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %band(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = band v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: and r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %bor(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = bor v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: orr r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %bxor(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = bxor v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: eor r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %bnot(i32) -> i32 {
|
||||
block0(v0: i32):
|
||||
v1 = bnot v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mvn r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %band_not(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = band_not v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: bic r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %bor_not(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = bor_not v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: orn r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
132
cranelift/filetests/filetests/vcode/arm32/bitops.clif
Normal file
132
cranelift/filetests/filetests/vcode/arm32/bitops.clif
Normal file
@@ -0,0 +1,132 @@
|
||||
test compile
|
||||
target arm
|
||||
|
||||
function %bitrev_i8(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
v1 = bitrev v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, r0, lsl #24
|
||||
; nextln: rbit r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %bitrev_i16(i16) -> i16 {
|
||||
block0(v0: i16):
|
||||
v1 = bitrev v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, r0, lsl #16
|
||||
; nextln: rbit r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %bitrev_i32(i32) -> i32 {
|
||||
block0(v0: i32):
|
||||
v1 = bitrev v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: rbit r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %clz_i8(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
v1 = clz v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxtb r0, r0
|
||||
; nextln: clz r0, r0
|
||||
; nextln: sub r0, r0, #24
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %clz_i16(i16) -> i16 {
|
||||
block0(v0: i16):
|
||||
v1 = clz v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxth r0, r0
|
||||
; nextln: clz r0, r0
|
||||
; nextln: sub r0, r0, #16
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %clz_i32(i32) -> i32 {
|
||||
block0(v0: i32):
|
||||
v1 = clz v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: clz r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ctz_i8(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
v1 = ctz v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxtb r0, r0
|
||||
; nextln: rbit r0, r0
|
||||
; nextln: clz r0, r0
|
||||
; nextln: sub r0, r0, #24
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ctz_i16(i16) -> i16 {
|
||||
block0(v0: i16):
|
||||
v1 = ctz v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxth r0, r0
|
||||
; nextln: rbit r0, r0
|
||||
; nextln: clz r0, r0
|
||||
; nextln: sub r0, r0, #16
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ctz_i32(i32) -> i32 {
|
||||
block0(v0: i32):
|
||||
v1 = ctz v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: rbit r0, r0
|
||||
; nextln: clz r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
60
cranelift/filetests/filetests/vcode/arm32/cond.clif
Normal file
60
cranelift/filetests/filetests/vcode/arm32/cond.clif
Normal file
@@ -0,0 +1,60 @@
|
||||
test compile
|
||||
target arm
|
||||
|
||||
function %icmp(i32, i32) -> b1 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = icmp eq v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: cmp r0, r1
|
||||
; nextln: ite eq ; mov r0, #1 ; mov r0, #0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ifcmp_trueif(i32, i32) -> b1 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: cmp r0, r1
|
||||
; nextln: ite eq ; mov r0, #1 ; mov r0, #0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %select(i32, i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32, v2: i32):
|
||||
v3 = select v0, v1, v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: cmp r0, #0
|
||||
; nextln: ite ne ; mov r0, r1 ; mov r0, r2
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %selectif(i32, i32, i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32, v2: i32, v3: i32):
|
||||
v4 = ifcmp v0, v1
|
||||
v5 = selectif.i32 eq v4, v2, v3
|
||||
return v5
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: cmp r0, r1
|
||||
; nextln: ite eq ; mov r0, r2 ; mov r0, r3
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
107
cranelift/filetests/filetests/vcode/arm32/constants.clif
Normal file
107
cranelift/filetests/filetests/vcode/arm32/constants.clif
Normal file
@@ -0,0 +1,107 @@
|
||||
test compile
|
||||
target arm
|
||||
|
||||
function %b1() -> b1 {
|
||||
block0:
|
||||
v0 = bconst.b1 true
|
||||
return v0
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, #1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %b8() -> b8 {
|
||||
block0:
|
||||
v0 = bconst.b8 false
|
||||
return v0
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, #0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %b16() -> b16 {
|
||||
block0:
|
||||
v0 = bconst.b16 true
|
||||
return v0
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, #1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %b32() -> b32 {
|
||||
block0:
|
||||
v0 = bconst.b32 false
|
||||
return v0
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, #0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %i8() -> i8 {
|
||||
block0:
|
||||
v0 = iconst.i8 0xff
|
||||
return v0
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, #255
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %i8() -> i16 {
|
||||
block0:
|
||||
v0 = iconst.i16 0xffff
|
||||
return v0
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, #65535
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %f() -> i32 {
|
||||
block0:
|
||||
v0 = iconst.i32 0xffff
|
||||
return v0
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, #65535
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %f() -> i32 {
|
||||
block0:
|
||||
v0 = iconst.i32 0xffffffff
|
||||
return v0
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, #65535
|
||||
; nextln: movt r0, #65535
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
131
cranelift/filetests/filetests/vcode/arm32/control-flow.clif
Normal file
131
cranelift/filetests/filetests/vcode/arm32/control-flow.clif
Normal file
@@ -0,0 +1,131 @@
|
||||
test compile
|
||||
target arm
|
||||
|
||||
function %brnz(b1) -> i32 {
|
||||
block0(v0: b1):
|
||||
brnz v0, block1
|
||||
jump block2
|
||||
|
||||
block1:
|
||||
v1 = iconst.i32 1
|
||||
return v1
|
||||
|
||||
block2:
|
||||
v2 = iconst.i32 2
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: Block 0:
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: and r0, r0, #1
|
||||
; nextln: cmp r0, #0
|
||||
; nextln: bne label1 ; b label2
|
||||
; check: Block 1:
|
||||
; check: mov r0, #1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
; check: Block 2:
|
||||
; check: mov r0, #2
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %brz(b1) -> i32 {
|
||||
block0(v0: b1):
|
||||
brz v0, block1
|
||||
jump block2
|
||||
|
||||
block1:
|
||||
v1 = iconst.i32 1
|
||||
return v1
|
||||
|
||||
block2:
|
||||
v2 = iconst.i32 2
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: Block 0:
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: and r0, r0, #1
|
||||
; nextln: cmp r0, #0
|
||||
; nextln: beq label1 ; b label2
|
||||
; check: Block 1:
|
||||
; check: mov r0, #1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
; check: Block 2:
|
||||
; check: mov r0, #2
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %trap() {
|
||||
block0:
|
||||
trap user0
|
||||
}
|
||||
|
||||
; check: udf #0
|
||||
|
||||
function %trapif(i32, i32) {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = ifcmp v0, v1
|
||||
trapif eq v2, user0
|
||||
return
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: cmp r0, r1
|
||||
; nextln: bne 2 ; udf #0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %debugtrap() {
|
||||
block0:
|
||||
debugtrap
|
||||
return
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: bkpt #0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %call(i32) -> i32 {
|
||||
fn0 = %f(i32) -> i32
|
||||
block0(v0: i32):
|
||||
v1 = call fn0(v0)
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: ldr r1, [pc, #4] ; b 4 ; data
|
||||
; nextln: blx r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
|
||||
function %call_indirect(i32, i32) -> i32 {
|
||||
sig0 = (i32) -> i32
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = call_indirect.i32 sig0, v1(v0)
|
||||
return v2
|
||||
}
|
||||
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: blx r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
80
cranelift/filetests/filetests/vcode/arm32/extend.clif
Normal file
80
cranelift/filetests/filetests/vcode/arm32/extend.clif
Normal file
@@ -0,0 +1,80 @@
|
||||
test compile
|
||||
target arm
|
||||
|
||||
function %uextend_i8_i32(i8) -> i32 {
|
||||
block0(v0: i8):
|
||||
v1 = uextend.i32 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxtb r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %uextend_i8_i16(i8) -> i16 {
|
||||
block0(v0: i8):
|
||||
v1 = uextend.i16 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxtb r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %uextend_i16_i32(i16) -> i32 {
|
||||
block0(v0: i16):
|
||||
v1 = uextend.i32 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxth r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %sextend_i8_i32(i8) -> i32 {
|
||||
block0(v0: i8):
|
||||
v1 = sextend.i32 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: sxtb r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %sextend_i8_i16(i8) -> i16 {
|
||||
block0(v0: i8):
|
||||
v1 = sextend.i16 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: sxtb r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %sextend_i16_i32(i16) -> i32 {
|
||||
block0(v0: i16):
|
||||
v1 = sextend.i32 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: sxth r0, r0
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
47
cranelift/filetests/filetests/vcode/arm32/params.clif
Normal file
47
cranelift/filetests/filetests/vcode/arm32/params.clif
Normal file
@@ -0,0 +1,47 @@
|
||||
test compile
|
||||
target arm
|
||||
|
||||
function %args(i32) -> i32 {
|
||||
sig0 = (i32, i32, i32, i32) -> i32
|
||||
block0(v0: i32):
|
||||
v1 = iconst.i32 1
|
||||
v2 = iconst.i32 2
|
||||
v3 = iconst.i32 3
|
||||
v4 = iconst.i32 4
|
||||
v5 = call_indirect.i32 sig0, v0(v1, v2, v3, v4)
|
||||
return v5
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: push {r4, ip}
|
||||
; nextln: virtual_sp_offset_adjust 8
|
||||
; nextln: mov r4, r0
|
||||
; nextln: mov r0, #1
|
||||
; nextln: mov r1, #2
|
||||
; nextln: mov r2, #3
|
||||
; nextln: mov r3, #4
|
||||
; nextln: blx r4
|
||||
; nextln: pop {r4, ip}
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %multi_return() -> i32, i32, i32, i32 {
|
||||
block0:
|
||||
v0 = iconst.i32 1
|
||||
v1 = iconst.i32 2
|
||||
v2 = iconst.i32 3
|
||||
v3 = iconst.i32 4
|
||||
return v0, v1, v2, v3
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: mov r0, #1
|
||||
; nextln: mov r1, #2
|
||||
; nextln: mov r2, #3
|
||||
; nextln: mov r3, #4
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
157
cranelift/filetests/filetests/vcode/arm32/shift-rotate.clif
Normal file
157
cranelift/filetests/filetests/vcode/arm32/shift-rotate.clif
Normal file
@@ -0,0 +1,157 @@
|
||||
test compile
|
||||
target arm
|
||||
|
||||
function %ishl_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
v2 = ishl v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxtb r1, r1
|
||||
; nextln: lsl r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ishl_i16(i16, i16) -> i16 {
|
||||
block0(v0: i16, v1: i16):
|
||||
v2 = ishl v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxth r1, r1
|
||||
; nextln: lsl r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ishl_i32(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = ishl v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: lsl r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ushr_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
v2 = ushr v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxtb r0, r0
|
||||
; nextln: uxtb r1, r1
|
||||
; nextln: lsr r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ushr_i16(i16, i16) -> i16 {
|
||||
block0(v0: i16, v1: i16):
|
||||
v2 = ushr v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: uxth r0, r0
|
||||
; nextln: uxth r1, r1
|
||||
; nextln: lsr r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ushr_i32(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = ushr v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: lsr r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %sshr_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
v2 = sshr v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: sxtb r0, r0
|
||||
; nextln: uxtb r1, r1
|
||||
; nextln: asr r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %sshr_i16(i16, i16) -> i16 {
|
||||
block0(v0: i16, v1: i16):
|
||||
v2 = sshr v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: sxth r0, r0
|
||||
; nextln: uxth r1, r1
|
||||
; nextln: asr r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %sshr_i32(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = sshr v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: asr r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %ror_i32(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = rotr v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: ror r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
|
||||
function %rotl_i32(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = rotl v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: push {fp, lr}
|
||||
; nextln: mov fp, sp
|
||||
; nextln: and r1, r1, #31
|
||||
; nextln: rsb r1, r1, #32
|
||||
; nextln: ror r0, r0, r1
|
||||
; nextln: mov sp, fp
|
||||
; nextln: pop {fp, lr}
|
||||
; nextln: bx lr
|
||||
Reference in New Issue
Block a user