Implement jump tables (#453)

* Add 'jump_table_entry' and 'indirect_jump' instructions.

* Update CodeSink to keep track of code size. Pretty up clif-util's disassembly output.

* Only disassemble the machine portion of output. Pretty print the read-only data after it.

* Update switch frontend code to use new br_table instruction w/ default.
This commit is contained in:
Tyler McMullen
2018-10-03 11:04:21 -06:00
committed by Dan Gohman
parent de1d82b4ba
commit 79cea5e18b
39 changed files with 627 additions and 100 deletions

View File

@@ -1402,3 +1402,41 @@ ebb0:
trap user0 ; bin: user0 0f 0b
}
; Tests for i64 jump table instructions.
function %I64_JT(i64 [%rdi]) {
jt0 = jump_table ebb1, ebb2, ebb3
ebb0(v0: i64 [%rdi]):
; Note: The next two lines will need to change whenever instructions are
; added or removed from this test.
[-, %rax] v1 = jump_table_base.i64 jt0 ; bin: 48 8d 05 00000039
[-, %r10] v2 = jump_table_base.i64 jt0 ; bin: 4c 8d 15 00000032
[-, %rbx] v10 = iconst.i64 1
[-, %r13] v11 = iconst.i64 2
[-, %rax] v20 = jump_table_entry.i64 v10, v1, 4, jt0 ; bin: 48 63 04 98
[-, %rax] v21 = jump_table_entry.i64 v10, v2, 4, jt0 ; bin: 49 63 04 9a
[-, %rax] v22 = jump_table_entry.i64 v11, v1, 4, jt0 ; bin: 4a 63 04 a8
[-, %rax] v23 = jump_table_entry.i64 v11, v2, 4, jt0 ; bin: 4b 63 04 aa
[-, %r10] v30 = jump_table_entry.i64 v10, v1, 4, jt0 ; bin: 4c 63 14 98
[-, %r10] v31 = jump_table_entry.i64 v10, v2, 4, jt0 ; bin: 4d 63 14 9a
[-, %r10] v32 = jump_table_entry.i64 v11, v1, 4, jt0 ; bin: 4e 63 14 a8
[-, %r10] v33 = jump_table_entry.i64 v11, v2, 4, jt0 ; bin: 4f 63 14 aa
fallthrough ebb10
ebb10:
indirect_jump_table_br v10, jt0 ; bin: ff e3
ebb11:
indirect_jump_table_br v11, jt0 ; bin: 41 ff e5
ebb1:
fallthrough ebb2
ebb2:
fallthrough ebb3
ebb3:
trap user0
}

View File

@@ -9,7 +9,9 @@ function u0:0(i64) system_v {
ebb0(v0: i64):
v1 = stack_addr.i64 ss0
v2 = load.i8 v1
br_table v2, jt0
br_table v2, ebb2, jt0
ebb2:
jump ebb1
ebb1:

View File

@@ -85,21 +85,22 @@ function %jumptable(i32) {
jt2 = jump_table 0, 0, ebb10, ebb40, ebb20, ebb30
ebb10(v3: i32):
br_table v3, jt2
trap user1
br_table v3, ebb50, jt2
ebb20:
trap user2
ebb30:
trap user3
ebb40:
trap user4
ebb50:
trap user1
}
; sameln: function %jumptable(i32) fast {
; check: jt2 = jump_table 0, 0, ebb10, ebb40, ebb20, ebb30
; check: jt200 = jump_table 0
; check: ebb10(v3: i32):
; nextln: br_table v3, jt2
; nextln: trap user1
; nextln: br_table v3, ebb50, jt2
; nextln:
; nextln: ebb20:
; nextln: trap user2
@@ -109,4 +110,7 @@ ebb40:
; nextln:
; nextln: ebb40:
; nextln: trap user4
; nextln:
; nextln: ebb50:
; nextln: trap user1
; nextln: }

View File

@@ -71,10 +71,12 @@ function %jump_table_args() {
jt1 = jump_table ebb1
ebb0:
v0 = iconst.i32 0
br_table v0, jt1 ; error: takes no arguments, but had target ebb1 with 1 arguments
return
br_table v0, ebb2, jt1 ; error: takes no arguments, but had target ebb1 with 1 arguments
ebb1(v5: i32):
return
ebb2:
return
}
function %jump_args() {

View File

@@ -51,7 +51,9 @@ function %br_table(i32) {
jt0 = jump_table ebb3, ebb1, 0, ebb2
ebb0(v0: i32):
br_table v0, jt0
br_table v0, ebb4, jt0
ebb4:
trap oob
ebb1: