From 2201e6249e40fb7b167b9609592f0b01887c9638 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 28 Aug 2017 14:54:35 -0700 Subject: [PATCH] Add Intel encodings for brz.b1 and brnz.b1. Use these encodings to test trapz.b1 and trapnz.b1. When a b1 value is stored in a register, only the low 8 bits are valid. This is so we can use the various setCC instructions to generate the b1 registers. --- .../filetests/isa/intel/legalize-custom.cton | 24 +++++++++++++++++++ lib/cretonne/meta/isa/intel/encodings.py | 12 ++++++++++ lib/cretonne/meta/isa/intel/recipes.py | 16 +++++++++++++ 3 files changed, 52 insertions(+) diff --git a/cranelift/filetests/isa/intel/legalize-custom.cton b/cranelift/filetests/isa/intel/legalize-custom.cton index ae63a56e0a..e8af47a460 100644 --- a/cranelift/filetests/isa/intel/legalize-custom.cton +++ b/cranelift/filetests/isa/intel/legalize-custom.cton @@ -28,3 +28,27 @@ ebb0(v1: i32): ; check: $new: ; nextln: return } + +function %cond_trap_b1(i32) { +ebb0(v1: i32): + v2 = icmp_imm eq v1, 6 + trapz v2 + return + ; check: $ebb0($v1: i32): + ; check: brnz $v2, $(new=$EBB) + ; nextln: trap + ; check: $new: + ; nextln: return +} + +function %cond_trap2_b1(i32) { +ebb0(v1: i32): + v2 = icmp_imm eq v1, 6 + trapnz v2 + return + ; check: $ebb0($v1: i32): + ; check: brz $v2, $(new=$EBB) + ; nextln: trap + ; check: $new: + ; nextln: return +} diff --git a/lib/cretonne/meta/isa/intel/encodings.py b/lib/cretonne/meta/isa/intel/encodings.py index 39b6812058..3b2a91a1f2 100644 --- a/lib/cretonne/meta/isa/intel/encodings.py +++ b/lib/cretonne/meta/isa/intel/encodings.py @@ -22,12 +22,14 @@ except ImportError: I32.legalize_type( default=narrow, + b1=expand, i32=intel_expand, f32=expand, f64=expand) I64.legalize_type( default=narrow, + b1=expand, i32=intel_expand, i64=intel_expand, f32=expand, @@ -238,6 +240,16 @@ I64.enc(base.jump, *r.jmpd(0xe9)) enc_i32_i64(base.brz, r.tjccb, 0x74) enc_i32_i64(base.brnz, r.tjccb, 0x75) +# Branch on a b1 value in a register only looks at the low 8 bits. See also +# bint encodings below. +I32.enc(base.brz.b1, *r.t8jccb_abcd(0x74)) +I64.enc(base.brz.b1, *r.t8jccb_abcd.rex(0x74)) +I64.enc(base.brz.b1, *r.t8jccb_abcd(0x74)) +I32.enc(base.brnz.b1, *r.t8jccb_abcd(0x75)) +I64.enc(base.brnz.b1, *r.t8jccb_abcd.rex(0x75)) +I64.enc(base.brnz.b1, *r.t8jccb_abcd(0x75)) + + # # Trap as ud2 # diff --git a/lib/cretonne/meta/isa/intel/recipes.py b/lib/cretonne/meta/isa/intel/recipes.py index 3e038e1208..1302350f7c 100644 --- a/lib/cretonne/meta/isa/intel/recipes.py +++ b/lib/cretonne/meta/isa/intel/recipes.py @@ -515,6 +515,22 @@ tjccb = TailRecipe( disp1(destination, func, sink); ''') +# 8-bit test-and-branch. +# +# Same as tjccb, but only looks at the low 8 bits of the register, for b1 +# types. +t8jccb_abcd = TailRecipe( + 't8jccb_abcd', Branch, size=1 + 2, ins=ABCD, outs=(), + branch_range=(2, 8), + emit=''' + // test8 r, r. + PUT_OP(0x84, rex2(in_reg0, in_reg0), sink); + modrm_rr(in_reg0, in_reg0, sink); + // Jcc instruction. + sink.put1(bits as u8); + disp1(destination, func, sink); + ''') + # Comparison that produces a `b1` result in a GPR. # # This is a macro of a `cmp` instruction followed by a `setCC` instruction.