Avoid infer_rex() and w() on the same x86 encoding template, resolves #1342

In cranelift x86 encodings, it seemed unintuitive to specialize Templates with both `infer_rex()`` and `w()`: if `w()` is specified, the REX.W bit must be set so a REX prefix is alway required--no need to infer it. This change forces us to write `rex().w()``--it's more explicit and shows more clearly what cranelift will emit. This change also modifies the tests that expected DynRex recipes.
This commit is contained in:
Andrew Brown
2020-03-31 08:43:17 -07:00
parent a325b62ade
commit d0daef6f60
6 changed files with 18 additions and 17 deletions

View File

@@ -156,7 +156,7 @@ impl PerCpuModeEncodings {
self.enc64(inst.bind(I32), template.infer_rex());
// I64 on x86_64: REX.W set; REX.RXB determined at runtime from registers.
self.enc64(inst.bind(I64), template.infer_rex().w());
self.enc64(inst.bind(I64), template.rex().w());
}
/// Adds I32/I64 encodings as appropriate for a typed instruction.
@@ -192,7 +192,7 @@ impl PerCpuModeEncodings {
self.enc64(inst.bind(B32), template.infer_rex());
// B64 on x86_64: REX.W set; REX.RXB determined at runtime from registers.
self.enc64(inst.bind(B64), template.infer_rex().w());
self.enc64(inst.bind(B64), template.rex().w());
}
/// Add encodings for `inst.i32` to X86_32.

View File

@@ -335,6 +335,7 @@ impl<'builder> Template<'builder> {
("Rex".to_string() + opcode, self.op_bytes.len() as u64 + 1)
}
RecipePrefixKind::InferRex => {
assert_eq!(self.w_bit, 0, "A REX.W bit always requires a REX prefix; avoid using `infer_rex().w()` and use `rex().w()` instead.");
// Hook up the right function for inferred compute_size().
assert!(
self.inferred_rex_compute_size.is_some(),

View File

@@ -15,7 +15,7 @@ block1:
; sameln: function %br_icmp(i64 [%rdi]) fast {
; nextln: block0(v0: i64):
; nextln: [RexOp1pu_id#b8] v1 = iconst.i64 0
; nextln: [DynRexOp1icscc#8039] v2 = icmp eq v0, v1
; nextln: [RexOp1icscc#8039] v2 = icmp eq v0, v1
; nextln: [RexOp1t8jccb#75] brnz v2, block1
; nextln: [Op1jmpb#eb] jump block1
; nextln:
@@ -37,7 +37,7 @@ block1(v2: i64):
; sameln: function %br_icmp_args(i64 [%rdi]) fast {
; nextln: block0(v0: i64):
; nextln: [RexOp1pu_id#b8] v1 = iconst.i64 0
; nextln: [DynRexOp1icscc#8039] v3 = icmp eq v0, v1
; nextln: [RexOp1icscc#8039] v3 = icmp eq v0, v1
; nextln: [RexOp1t8jccb#75] brnz v3, block1(v0)
; nextln: [Op1jmpb#eb] jump block1(v0)
; nextln:

View File

@@ -22,7 +22,7 @@ function u0:2691(i32 [%rdi], i32 [%rsi], i64 vmctx [%r14]) -> i64 uext [%rax] ba
block3(v8: i32 [%rdi], v19: i32 [%rsi]):
@0005 [RexOp1ldDisp8#808b,%rax] v7 = load.i64 v2+48
@0005 [DynRexOp1rcmp_ib#f083,%rflags] v91 = ifcmp_imm v7, 0
@0005 [RexOp1rcmp_ib#f083,%rflags] v91 = ifcmp_imm v7, 0
@0005 [trapif#00] trapif ne v91, interrupt
[DynRexOp1umr#89,%rax] v105 = copy v8
@000b [DynRexOp1r_ib#83,%rax] v10 = iadd_imm v105, 1

View File

@@ -3,7 +3,7 @@ target x86_64
function %dual_loads(i64, i64) -> i64 {
block0(v0: i64, v1: i64):
[DynRexOp1rr#8001] v3 = iadd v0, v1
[RexOp1rr#8001] v3 = iadd v0, v1
v4 = load.i64 v3
v5 = uload8.i64 v3
v6 = sload8.i64 v3
@@ -29,7 +29,7 @@ block0(v0: i64, v1: i64):
function %dual_loads2(i64, i64) -> i64 {
block0(v0: i64, v1: i64):
[DynRexOp1rr#8001] v3 = iadd v0, v1
[RexOp1rr#8001] v3 = iadd v0, v1
v4 = load.i64 v3+1
v5 = uload8.i64 v3+1
v6 = sload8.i64 v3+1
@@ -55,7 +55,7 @@ block0(v0: i64, v1: i64):
function %dual_stores(i64, i64, i64) {
block0(v0: i64, v1: i64, v2: i64):
[DynRexOp1rr#8001] v3 = iadd v0, v1
[RexOp1rr#8001] v3 = iadd v0, v1
[RexOp1st#8089] store.i64 v2, v3
[RexOp1st#88] istore8.i64 v2, v3
[RexMp1st#189] istore16.i64 v2, v3
@@ -75,7 +75,7 @@ block0(v0: i64, v1: i64, v2: i64):
function %dual_stores2(i64, i64, i64) {
block0(v0: i64, v1: i64, v2: i64):
[DynRexOp1rr#8001] v3 = iadd v0, v1
[RexOp1rr#8001] v3 = iadd v0, v1
[RexOp1stDisp8#8089] store.i64 v2, v3+1
[RexOp1stDisp8#88] istore8.i64 v2, v3+1
[RexMp1stDisp8#189] istore16.i64 v2, v3+1

View File

@@ -40,9 +40,9 @@ function %pr227(i32 [%rdi], i32 [%rsi], i32 [%rdx], i32 [%rcx], i64 vmctx [%r8])
block16:
[RexOp1pu_id#b8] v21 = iconst.i32 0
[RexOp1umr#89] v79 = uextend.i64 v5
[DynRexOp1r_ib#8083] v80 = iadd_imm.i64 v4, 0
[RexOp1r_ib#8083] v80 = iadd_imm.i64 v4, 0
[RexOp1ld#808b] v81 = load.i64 v80
[DynRexOp1rr#8001] v22 = iadd v81, v79
[RexOp1rr#8001] v22 = iadd v81, v79
[RexMp1st#189] istore16 v21, v22
[Op1jmpb#eb] jump block9
@@ -81,14 +81,14 @@ function %pr227(i32 [%rdi], i32 [%rsi], i32 [%rdx], i32 [%rcx], i64 vmctx [%r8])
block19:
[RexOp1umr#89] v82 = uextend.i64 v52
[DynRexOp1r_ib#8083] v83 = iadd_imm.i64 v4, 0
[RexOp1r_ib#8083] v83 = iadd_imm.i64 v4, 0
[RexOp1ld#808b] v84 = load.i64 v83
[DynRexOp1rr#8001] v57 = iadd v84, v82
[RexOp1rr#8001] v57 = iadd v84, v82
[RexOp1ld#8b] v58 = load.i32 v57
[RexOp1umr#89] v85 = uextend.i64 v58
[DynRexOp1r_ib#8083] v86 = iadd_imm.i64 v4, 0
[RexOp1r_ib#8083] v86 = iadd_imm.i64 v4, 0
[RexOp1ld#808b] v87 = load.i64 v86
[DynRexOp1rr#8001] v64 = iadd v87, v85
[RexOp1rr#8001] v64 = iadd v87, v85
[RexOp1st#88] istore8 v59, v64
[RexOp1pu_id#b8] v65 = iconst.i32 0
[Op1jmpb#eb] jump block13(v65)
@@ -98,9 +98,9 @@ function %pr227(i32 [%rdi], i32 [%rsi], i32 [%rdx], i32 [%rcx], i64 vmctx [%r8])
block13(v51: i32):
[RexOp1umr#89] v88 = uextend.i64 v45
[DynRexOp1r_ib#8083] v89 = iadd_imm.i64 v4, 0
[RexOp1r_ib#8083] v89 = iadd_imm.i64 v4, 0
[RexOp1ld#808b] v90 = load.i64 v89
[DynRexOp1rr#8001] v71 = iadd v90, v88
[RexOp1rr#8001] v71 = iadd v90, v88
[RexOp1st#89] store v51, v71
[Op1jmpb#eb] jump block12