Add a "colocated" flag to symbol references. (#298)
This adds a "colocated" flag to function and symbolic global variables which indicates that they are defined along with the current function, so they can use PC-relative addressing. This also changes the function decl syntax; the name now always precedes the signature, and the "function" keyword is no longer included.
This commit is contained in:
@@ -4,7 +4,7 @@ isa riscv
|
||||
|
||||
function %RV32I(i32 link [%x1]) -> i32 link [%x1] {
|
||||
sig0 = ()
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
|
||||
ebb0(v9999: i32):
|
||||
[-,%x10] v1 = iconst.i32 1
|
||||
|
||||
@@ -17,8 +17,8 @@ ebb0(v0: i64):
|
||||
}
|
||||
|
||||
function %split_call_arg(i32) {
|
||||
fn1 = function %foo(i64)
|
||||
fn2 = function %foo(i32, i64)
|
||||
fn1 = %foo(i64)
|
||||
fn2 = %foo(i32, i64)
|
||||
ebb0(v0: i32):
|
||||
v1 = uextend.i64 v0
|
||||
call fn1(v1)
|
||||
@@ -30,7 +30,7 @@ ebb0(v0: i32):
|
||||
}
|
||||
|
||||
function %split_ret_val() {
|
||||
fn1 = function %foo() -> i64
|
||||
fn1 = %foo() -> i64
|
||||
ebb0:
|
||||
v1 = call fn1()
|
||||
; check: ebb0($(link=$V): i32):
|
||||
@@ -45,7 +45,7 @@ ebb1(v10: i64):
|
||||
|
||||
; First return value is fine, second one is expanded.
|
||||
function %split_ret_val2() {
|
||||
fn1 = function %foo() -> i32, i64
|
||||
fn1 = %foo() -> i32, i64
|
||||
ebb0:
|
||||
v1, v2 = call fn1()
|
||||
; check: ebb0($(link=$V): i32):
|
||||
@@ -70,7 +70,7 @@ ebb0(v1: i8, v2: i8, v3: i8):
|
||||
|
||||
; Function produces single return value, still need to copy.
|
||||
function %ext_ret_val() {
|
||||
fn1 = function %foo() -> i8 sext
|
||||
fn1 = %foo() -> i8 sext
|
||||
ebb0:
|
||||
v1 = call fn1()
|
||||
; check: ebb0($V: i32):
|
||||
@@ -124,7 +124,7 @@ ebb0(v0: i32, v1: f32x2):
|
||||
; 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)
|
||||
fn1 = %foo(i64, i64, i64, i64, i32)
|
||||
ebb0(v0: i32):
|
||||
v1 = iconst.i64 1
|
||||
call fn1(v1, v1, v1, v1, v0)
|
||||
|
||||
@@ -27,9 +27,9 @@ function %parse_encoding(i32 [%x5]) -> i32 [%x10] {
|
||||
; check: sig5 = () -> f32 [0] system_v
|
||||
|
||||
; function + signature
|
||||
fn0 = function %bar(i32 [%x10]) -> b1 [%x10] system_v
|
||||
fn0 = %bar(i32 [%x10]) -> b1 [%x10] system_v
|
||||
; check: sig6 = (i32 [%x10]) -> b1 [%x10] system_v
|
||||
; nextln: fn0 = sig6 %bar
|
||||
; nextln: fn0 = %bar sig6
|
||||
|
||||
ebb0(v0: i32):
|
||||
return v0
|
||||
|
||||
@@ -2,7 +2,7 @@ test verifier
|
||||
isa riscv
|
||||
|
||||
function %RV32I(i32 link [%x1]) -> i32 link [%x1] {
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
|
||||
ebb0(v9999: i32):
|
||||
; iconst.i32 needs legalizing, so it should throw a
|
||||
@@ -11,7 +11,7 @@ ebb0(v9999: i32):
|
||||
}
|
||||
|
||||
function %RV32I(i32 link [%x1]) -> i32 link [%x1] {
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
|
||||
ebb0(v9999: i32):
|
||||
v1 = iconst.i32 1
|
||||
|
||||
@@ -21,7 +21,7 @@ ebb0:
|
||||
|
||||
function %pass_stack_int64(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 vmctx) spiderwasm {
|
||||
sig0 = (i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 vmctx) spiderwasm
|
||||
fn0 = sig0 u0:0
|
||||
fn0 = u0:0 sig0
|
||||
|
||||
ebb0(v0: i64, v1: i64, v2: i64, v3: i64, v4: i64, v5: i64, v6: i64, v7: i64, v8: i64, v9: i64, v10: i64, v11: i64, v12: i64, v13: i64, v14: i64, v15: i64, v16: i64, v17: i64, v18: i64, v19: i64, v20: i64):
|
||||
call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
|
||||
|
||||
@@ -12,7 +12,7 @@ isa x86 haswell
|
||||
; Tests from binary32.cton affected by allones_funcaddrs.
|
||||
function %I32() {
|
||||
sig0 = ()
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
|
||||
ebb0:
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ isa x86 haswell
|
||||
; Tests from binary64.cton affected by allones_funcaddrs.
|
||||
function %I64() {
|
||||
sig0 = ()
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
|
||||
ebb0:
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ isa x86 haswell
|
||||
|
||||
function %I32() {
|
||||
sig0 = ()
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
|
||||
gv0 = globalsym %some_gv
|
||||
|
||||
|
||||
@@ -13,9 +13,11 @@ isa x86 haswell
|
||||
; Tests for i64 instructions.
|
||||
function %I64() {
|
||||
sig0 = ()
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
fn1 = colocated %bar()
|
||||
|
||||
gv0 = globalsym %some_gv
|
||||
gv1 = globalsym colocated %some_gv
|
||||
|
||||
; Use incoming_arg stack slots because they won't be relocated by the frame
|
||||
; layout.
|
||||
@@ -29,6 +31,9 @@ ebb0:
|
||||
; asm: call foo@PLT
|
||||
call fn0() ; bin: e8 PLTRel4(%foo-4) 00000000
|
||||
|
||||
; asm: call foo
|
||||
call fn1() ; bin: e8 PCRel4(%bar-4) 00000000
|
||||
|
||||
; asm: mov 0x0(%rip), %rax
|
||||
[-,%rax] v0 = func_addr.i64 fn0 ; bin: 48 8b 05 GOTPCRel4(%foo-4) 00000000
|
||||
; asm: mov 0x0(%rip), %rsi
|
||||
@@ -50,5 +55,12 @@ ebb0:
|
||||
; asm: mov 0x0(%rip), %r10
|
||||
[-,%r10] v5 = globalsym_addr.i64 gv0 ; bin: 4c 8b 15 GOTPCRel4(%some_gv-4) 00000000
|
||||
|
||||
; asm: lea 0x0(%rip), %rcx
|
||||
[-,%rcx] v6 = globalsym_addr.i64 gv1 ; bin: 48 8d 0d PCRel4(%some_gv-4) 00000000
|
||||
; asm: lea 0x0(%rip), %rsi
|
||||
[-,%rsi] v7 = globalsym_addr.i64 gv1 ; bin: 48 8d 35 PCRel4(%some_gv-4) 00000000
|
||||
; asm: lea 0x0(%rip), %r10
|
||||
[-,%r10] v8 = globalsym_addr.i64 gv1 ; bin: 4c 8d 15 PCRel4(%some_gv-4) 00000000
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ isa x86 haswell
|
||||
; Tests for i64 instructions.
|
||||
function %I64() {
|
||||
sig0 = ()
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
|
||||
gv0 = globalsym %some_gv
|
||||
|
||||
@@ -473,12 +473,6 @@ ebb0:
|
||||
; asm: movzbq %dl, %rsi
|
||||
[-,%rsi] v351 = bint.i64 v301 ; bin: 0f b6 f2
|
||||
|
||||
; TODO: x86-64 can't encode a direct call to an arbitrary 64-bit address in
|
||||
; a single instruction. When we add a concept of colocated definitions, this
|
||||
; test can be re-enabled.
|
||||
; disabled: asm: call foo
|
||||
; disabled: call fn0() ; bin: e8 PCRel4(%foo-4) 00000000
|
||||
|
||||
; asm: movabsq $0, %rcx
|
||||
[-,%rcx] v400 = func_addr.i64 fn0 ; bin: 48 b9 Abs8(%foo) 0000000000000000
|
||||
; asm: movabsq $0, %rsi
|
||||
@@ -713,7 +707,7 @@ ebb0:
|
||||
; be done by an instruction shrinking pass.
|
||||
function %I32() {
|
||||
sig0 = ()
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
|
||||
ss0 = incoming_arg 8, offset 0
|
||||
ss1 = incoming_arg 1024, offset -1024
|
||||
|
||||
@@ -12,5 +12,5 @@ ebb0(v0: f32):
|
||||
}
|
||||
; check: function %floor(f32 [%xmm0]) -> f32 [%xmm0] system_v {
|
||||
; check: sig0 = (f32) -> f32 system_v
|
||||
; check: fn0 = sig0 %FloorF32
|
||||
; check: fn0 = %FloorF32 sig0
|
||||
; check: v1 = call fn0(v0)
|
||||
|
||||
@@ -45,7 +45,7 @@ ebb0:
|
||||
; A function performing a call.
|
||||
|
||||
function %call() {
|
||||
fn0 = function %foo()
|
||||
fn0 = %foo()
|
||||
|
||||
ebb0:
|
||||
call fn0()
|
||||
@@ -55,7 +55,7 @@ ebb0:
|
||||
; check: function %call(i64 fp [%rbp]) -> i64 fp [%rbp] system_v {
|
||||
; nextln: ss0 = incoming_arg 16, offset -16
|
||||
; nextln: sig0 = () system_v
|
||||
; nextln: fn0 = sig0 %foo
|
||||
; nextln: fn0 = %foo sig0
|
||||
; nextln:
|
||||
; nextln: ebb0(v0: i64 [%rbp]):
|
||||
; nextln: x86_push v0
|
||||
|
||||
Reference in New Issue
Block a user