To keep cross-compiling straightforward, Cretonne shouldn't have any behavior that depends on the host. This renames the "Native" calling convention to "SystemV", which has a defined meaning for each target, so that it's clear that the calling convention doesn't change depending on what host Cretonne is running on.
135 lines
3.6 KiB
Plaintext
135 lines
3.6 KiB
Plaintext
; Test legalizer's handling of ABI boundaries.
|
|
test legalizer
|
|
isa riscv
|
|
|
|
; regex: V=v\d+
|
|
; regex: SS=ss\d+
|
|
; regex: WS=\s+
|
|
|
|
function %int_split_args(i64) -> i64 {
|
|
ebb0(v0: i64):
|
|
; check: ebb0($(v0l=$V): i32, $(v0h=$V): i32, $(link=$V): i32):
|
|
; check: v0 = iconcat $v0l, $v0h
|
|
v1 = iadd_imm v0, 1
|
|
; check: $(v1l=$V), $(v1h=$V) = isplit v1
|
|
; check: return $v1l, $v1h, $link
|
|
return v1
|
|
}
|
|
|
|
function %split_call_arg(i32) {
|
|
fn1 = function %foo(i64)
|
|
fn2 = function %foo(i32, i64)
|
|
ebb0(v0: i32):
|
|
v1 = uextend.i64 v0
|
|
call fn1(v1)
|
|
; check: $(v1l=$V), $(v1h=$V) = isplit v1
|
|
; check: call fn1($v1l, $v1h)
|
|
call fn2(v0, v1)
|
|
; check: call fn2(v0, $V, $V)
|
|
return
|
|
}
|
|
|
|
function %split_ret_val() {
|
|
fn1 = function %foo() -> i64
|
|
ebb0:
|
|
v1 = call fn1()
|
|
; check: ebb0($(link=$V): i32):
|
|
; nextln: $(v1l=$V), $(v1h=$V) = call fn1()
|
|
; check: v1 = iconcat $v1l, $v1h
|
|
jump ebb1(v1)
|
|
; check: jump ebb1(v1)
|
|
|
|
ebb1(v10: i64):
|
|
jump ebb1(v10)
|
|
}
|
|
|
|
; First return value is fine, second one is expanded.
|
|
function %split_ret_val2() {
|
|
fn1 = function %foo() -> i32, i64
|
|
ebb0:
|
|
v1, v2 = call fn1()
|
|
; check: ebb0($(link=$V): i32):
|
|
; nextln: v1, $(v2l=$V), $(v2h=$V) = call fn1()
|
|
; check: v2 = iconcat $v2l, $v2h
|
|
jump ebb1(v1, v2)
|
|
; check: jump ebb1(v1, v2)
|
|
|
|
ebb1(v9: i32, v10: i64):
|
|
jump ebb1(v9, v10)
|
|
}
|
|
|
|
function %int_ext(i8, i8 sext, i8 uext) -> i8 uext {
|
|
ebb0(v1: i8, v2: i8, v3: i8):
|
|
; check: ebb0(v1: i8, $(v2x=$V): i32, $(v3x=$V): i32, $(link=$V): i32):
|
|
; check: v2 = ireduce.i8 $v2x
|
|
; check: v3 = ireduce.i8 $v3x
|
|
; check: $(v1x=$V) = uextend.i32 v1
|
|
; check: return $v1x, $link
|
|
return v1
|
|
}
|
|
|
|
; Function produces single return value, still need to copy.
|
|
function %ext_ret_val() {
|
|
fn1 = function %foo() -> i8 sext
|
|
ebb0:
|
|
v1 = call fn1()
|
|
; check: ebb0($V: i32):
|
|
; nextln: $(rv=$V) = call fn1()
|
|
; check: v1 = ireduce.i8 $rv
|
|
jump ebb1(v1)
|
|
; check: jump ebb1(v1)
|
|
|
|
ebb1(v10: i8):
|
|
jump ebb1(v10)
|
|
}
|
|
|
|
function %vector_split_args(i64x4) -> i64x4 {
|
|
ebb0(v0: i64x4):
|
|
; check: ebb0($(v0al=$V): i32, $(v0ah=$V): i32, $(v0bl=$V): i32, $(v0bh=$V): i32, $(v0cl=$V): i32, $(v0ch=$V): i32, $(v0dl=$V): i32, $(v0dh=$V): i32, $(link=$V): i32):
|
|
; check: $(v0a=$V) = iconcat $v0al, $v0ah
|
|
; check: $(v0b=$V) = iconcat $v0bl, $v0bh
|
|
; check: $(v0ab=$V) = vconcat $v0a, $v0b
|
|
; check: $(v0c=$V) = iconcat $v0cl, $v0ch
|
|
; check: $(v0d=$V) = iconcat $v0dl, $v0dh
|
|
; check: $(v0cd=$V) = vconcat $v0c, $v0d
|
|
; check: v0 = vconcat $v0ab, $v0cd
|
|
v1 = bxor v0, v0
|
|
; check: $(v1ab=$V), $(v1cd=$V) = vsplit v1
|
|
; check: $(v1a=$V), $(v1b=$V) = vsplit $v1ab
|
|
; check: $(v1al=$V), $(v1ah=$V) = isplit $v1a
|
|
; check: $(v1bl=$V), $(v1bh=$V) = isplit $v1b
|
|
; check: $(v1c=$V), $(v1d=$V) = vsplit $v1cd
|
|
; check: $(v1cl=$V), $(v1ch=$V) = isplit $v1c
|
|
; check: $(v1dl=$V), $(v1dh=$V) = isplit $v1d
|
|
; check: return $v1al, $v1ah, $v1bl, $v1bh, $v1cl, $v1ch, $v1dl, $v1dh, $link
|
|
return v1
|
|
}
|
|
|
|
function %indirect(i32) {
|
|
sig1 = () system_v
|
|
ebb0(v0: i32):
|
|
call_indirect sig1, v0()
|
|
return
|
|
}
|
|
|
|
; The first argument to call_indirect doesn't get altered.
|
|
function %indirect_arg(i32, f32x2) {
|
|
sig1 = (f32x2) system_v
|
|
ebb0(v0: i32, v1: f32x2):
|
|
call_indirect sig1, v0(v1)
|
|
; check: call_indirect sig1, v0($V, $V)
|
|
return
|
|
}
|
|
|
|
; Call a function that takes arguments on the stack.
|
|
function %stack_args(i32) {
|
|
; check: $(ss0=$SS) = outgoing_arg 4
|
|
fn1 = function %foo(i64, i64, i64, i64, i32)
|
|
ebb0(v0: i32):
|
|
v1 = iconst.i64 1
|
|
call fn1(v1, v1, v1, v1, v0)
|
|
; check: [GPsp#48,$ss0]$WS $(v0s=$V) = spill v0
|
|
; check: call fn1($(=.*), $v0s)
|
|
return
|
|
}
|