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:
@@ -156,7 +156,7 @@ impl PerCpuModeEncodings {
|
|||||||
self.enc64(inst.bind(I32), template.infer_rex());
|
self.enc64(inst.bind(I32), template.infer_rex());
|
||||||
|
|
||||||
// I64 on x86_64: REX.W set; REX.RXB determined at runtime from registers.
|
// 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.
|
/// Adds I32/I64 encodings as appropriate for a typed instruction.
|
||||||
@@ -192,7 +192,7 @@ impl PerCpuModeEncodings {
|
|||||||
self.enc64(inst.bind(B32), template.infer_rex());
|
self.enc64(inst.bind(B32), template.infer_rex());
|
||||||
|
|
||||||
// B64 on x86_64: REX.W set; REX.RXB determined at runtime from registers.
|
// 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.
|
/// Add encodings for `inst.i32` to X86_32.
|
||||||
|
|||||||
@@ -335,6 +335,7 @@ impl<'builder> Template<'builder> {
|
|||||||
("Rex".to_string() + opcode, self.op_bytes.len() as u64 + 1)
|
("Rex".to_string() + opcode, self.op_bytes.len() as u64 + 1)
|
||||||
}
|
}
|
||||||
RecipePrefixKind::InferRex => {
|
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().
|
// Hook up the right function for inferred compute_size().
|
||||||
assert!(
|
assert!(
|
||||||
self.inferred_rex_compute_size.is_some(),
|
self.inferred_rex_compute_size.is_some(),
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ block1:
|
|||||||
; sameln: function %br_icmp(i64 [%rdi]) fast {
|
; sameln: function %br_icmp(i64 [%rdi]) fast {
|
||||||
; nextln: block0(v0: i64):
|
; nextln: block0(v0: i64):
|
||||||
; nextln: [RexOp1pu_id#b8] v1 = iconst.i64 0
|
; 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: [RexOp1t8jccb#75] brnz v2, block1
|
||||||
; nextln: [Op1jmpb#eb] jump block1
|
; nextln: [Op1jmpb#eb] jump block1
|
||||||
; nextln:
|
; nextln:
|
||||||
@@ -37,7 +37,7 @@ block1(v2: i64):
|
|||||||
; sameln: function %br_icmp_args(i64 [%rdi]) fast {
|
; sameln: function %br_icmp_args(i64 [%rdi]) fast {
|
||||||
; nextln: block0(v0: i64):
|
; nextln: block0(v0: i64):
|
||||||
; nextln: [RexOp1pu_id#b8] v1 = iconst.i64 0
|
; 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: [RexOp1t8jccb#75] brnz v3, block1(v0)
|
||||||
; nextln: [Op1jmpb#eb] jump block1(v0)
|
; nextln: [Op1jmpb#eb] jump block1(v0)
|
||||||
; nextln:
|
; nextln:
|
||||||
|
|||||||
@@ -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]):
|
block3(v8: i32 [%rdi], v19: i32 [%rsi]):
|
||||||
@0005 [RexOp1ldDisp8#808b,%rax] v7 = load.i64 v2+48
|
@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
|
@0005 [trapif#00] trapif ne v91, interrupt
|
||||||
[DynRexOp1umr#89,%rax] v105 = copy v8
|
[DynRexOp1umr#89,%rax] v105 = copy v8
|
||||||
@000b [DynRexOp1r_ib#83,%rax] v10 = iadd_imm v105, 1
|
@000b [DynRexOp1r_ib#83,%rax] v10 = iadd_imm v105, 1
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ target x86_64
|
|||||||
|
|
||||||
function %dual_loads(i64, i64) -> i64 {
|
function %dual_loads(i64, i64) -> i64 {
|
||||||
block0(v0: i64, v1: i64):
|
block0(v0: i64, v1: i64):
|
||||||
[DynRexOp1rr#8001] v3 = iadd v0, v1
|
[RexOp1rr#8001] v3 = iadd v0, v1
|
||||||
v4 = load.i64 v3
|
v4 = load.i64 v3
|
||||||
v5 = uload8.i64 v3
|
v5 = uload8.i64 v3
|
||||||
v6 = sload8.i64 v3
|
v6 = sload8.i64 v3
|
||||||
@@ -29,7 +29,7 @@ block0(v0: i64, v1: i64):
|
|||||||
|
|
||||||
function %dual_loads2(i64, i64) -> i64 {
|
function %dual_loads2(i64, i64) -> i64 {
|
||||||
block0(v0: i64, v1: i64):
|
block0(v0: i64, v1: i64):
|
||||||
[DynRexOp1rr#8001] v3 = iadd v0, v1
|
[RexOp1rr#8001] v3 = iadd v0, v1
|
||||||
v4 = load.i64 v3+1
|
v4 = load.i64 v3+1
|
||||||
v5 = uload8.i64 v3+1
|
v5 = uload8.i64 v3+1
|
||||||
v6 = sload8.i64 v3+1
|
v6 = sload8.i64 v3+1
|
||||||
@@ -55,7 +55,7 @@ block0(v0: i64, v1: i64):
|
|||||||
|
|
||||||
function %dual_stores(i64, i64, i64) {
|
function %dual_stores(i64, i64, i64) {
|
||||||
block0(v0: i64, v1: i64, v2: 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#8089] store.i64 v2, v3
|
||||||
[RexOp1st#88] istore8.i64 v2, v3
|
[RexOp1st#88] istore8.i64 v2, v3
|
||||||
[RexMp1st#189] istore16.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) {
|
function %dual_stores2(i64, i64, i64) {
|
||||||
block0(v0: i64, v1: i64, v2: 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#8089] store.i64 v2, v3+1
|
||||||
[RexOp1stDisp8#88] istore8.i64 v2, v3+1
|
[RexOp1stDisp8#88] istore8.i64 v2, v3+1
|
||||||
[RexMp1stDisp8#189] istore16.i64 v2, v3+1
|
[RexMp1stDisp8#189] istore16.i64 v2, v3+1
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ function %pr227(i32 [%rdi], i32 [%rsi], i32 [%rdx], i32 [%rcx], i64 vmctx [%r8])
|
|||||||
block16:
|
block16:
|
||||||
[RexOp1pu_id#b8] v21 = iconst.i32 0
|
[RexOp1pu_id#b8] v21 = iconst.i32 0
|
||||||
[RexOp1umr#89] v79 = uextend.i64 v5
|
[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
|
[RexOp1ld#808b] v81 = load.i64 v80
|
||||||
[DynRexOp1rr#8001] v22 = iadd v81, v79
|
[RexOp1rr#8001] v22 = iadd v81, v79
|
||||||
[RexMp1st#189] istore16 v21, v22
|
[RexMp1st#189] istore16 v21, v22
|
||||||
[Op1jmpb#eb] jump block9
|
[Op1jmpb#eb] jump block9
|
||||||
|
|
||||||
@@ -81,14 +81,14 @@ function %pr227(i32 [%rdi], i32 [%rsi], i32 [%rdx], i32 [%rcx], i64 vmctx [%r8])
|
|||||||
|
|
||||||
block19:
|
block19:
|
||||||
[RexOp1umr#89] v82 = uextend.i64 v52
|
[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
|
[RexOp1ld#808b] v84 = load.i64 v83
|
||||||
[DynRexOp1rr#8001] v57 = iadd v84, v82
|
[RexOp1rr#8001] v57 = iadd v84, v82
|
||||||
[RexOp1ld#8b] v58 = load.i32 v57
|
[RexOp1ld#8b] v58 = load.i32 v57
|
||||||
[RexOp1umr#89] v85 = uextend.i64 v58
|
[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
|
[RexOp1ld#808b] v87 = load.i64 v86
|
||||||
[DynRexOp1rr#8001] v64 = iadd v87, v85
|
[RexOp1rr#8001] v64 = iadd v87, v85
|
||||||
[RexOp1st#88] istore8 v59, v64
|
[RexOp1st#88] istore8 v59, v64
|
||||||
[RexOp1pu_id#b8] v65 = iconst.i32 0
|
[RexOp1pu_id#b8] v65 = iconst.i32 0
|
||||||
[Op1jmpb#eb] jump block13(v65)
|
[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):
|
block13(v51: i32):
|
||||||
[RexOp1umr#89] v88 = uextend.i64 v45
|
[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
|
[RexOp1ld#808b] v90 = load.i64 v89
|
||||||
[DynRexOp1rr#8001] v71 = iadd v90, v88
|
[RexOp1rr#8001] v71 = iadd v90, v88
|
||||||
[RexOp1st#89] store v51, v71
|
[RexOp1st#89] store v51, v71
|
||||||
[Op1jmpb#eb] jump block12
|
[Op1jmpb#eb] jump block12
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user