From 06bab60fcc765954545fd12d58ad5ebb0a9214b1 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 26 Jul 2017 14:55:26 -0700 Subject: [PATCH] Add support for type variable wildcards in bound instructions. Instructions will multiple type variables can now use `any` to indicate encodings that don't care about the value of a secondary type variable: ishl.i32.any instead of ishl.i32.i32 This is only allowed for secondary type variables (which are converted to instruction predicates). The controlling type variable must still be fully specified because it is used to key the encoding tables. --- lib/cretonne/meta/cdsl/instructions.py | 5 +++ lib/cretonne/meta/cdsl/isa.py | 3 ++ lib/cretonne/meta/isa/intel/encodings.py | 56 ++++++++++++------------ 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/lib/cretonne/meta/cdsl/instructions.py b/lib/cretonne/meta/cdsl/instructions.py index 9d23dea89e..6dec0b7dff 100644 --- a/lib/cretonne/meta/cdsl/instructions.py +++ b/lib/cretonne/meta/cdsl/instructions.py @@ -314,6 +314,7 @@ class Instruction(object): >>> iadd.i32 """ + assert name != 'any', 'Wildcard not allowed for ctrl_typevar' return self.bind(ValueType.by_name(name)) def fully_bound(self): @@ -386,6 +387,10 @@ class BoundInstruction(object): >>> uext.i32.i8 """ + if name == 'any': + # This is a wild card bind represented as a None type variable. + return self.bind(None) + return self.bind(ValueType.by_name(name)) def fully_bound(self): diff --git a/lib/cretonne/meta/cdsl/isa.py b/lib/cretonne/meta/cdsl/isa.py index 1e08ca0e4f..487001d9e1 100644 --- a/lib/cretonne/meta/cdsl/isa.py +++ b/lib/cretonne/meta/cdsl/isa.py @@ -424,6 +424,9 @@ class Encoding(object): # Add secondary type variables to the instruction predicate. if len(self.typevars) > 1: for tv, vt in zip(self.inst.other_typevars, self.typevars[1:]): + # A None tv is an 'any' wild card: `ishl.i32.any`. + if vt is None: + continue typred = TypePredicate.typevar_check(self.inst, tv, vt) instp = And.combine(instp, typred) diff --git a/lib/cretonne/meta/isa/intel/encodings.py b/lib/cretonne/meta/isa/intel/encodings.py index b59dd8d9af..df95cf7f48 100644 --- a/lib/cretonne/meta/isa/intel/encodings.py +++ b/lib/cretonne/meta/isa/intel/encodings.py @@ -104,10 +104,10 @@ for inst, rrr in [ (base.ishl, 4), (base.ushr, 5), (base.sshr, 7)]: - I32.enc(inst.i32.i32, *r.rc(0xd3, rrr=rrr)) - I64.enc(inst.i64.i64, *r.rc.rex(0xd3, rrr=rrr, w=1)) - I64.enc(inst.i32.i32, *r.rc.rex(0xd3, rrr=rrr)) - I64.enc(inst.i32.i32, *r.rc(0xd3, rrr=rrr)) + I32.enc(inst.i32.any, *r.rc(0xd3, rrr=rrr)) + I64.enc(inst.i64.any, *r.rc.rex(0xd3, rrr=rrr, w=1)) + I64.enc(inst.i32.any, *r.rc.rex(0xd3, rrr=rrr)) + I64.enc(inst.i32.any, *r.rc(0xd3, rrr=rrr)) # Population count. I32.enc(base.popcnt.i32, *r.urm(0xf3, 0x0f, 0xb8), isap=cfg.use_popcnt) @@ -131,37 +131,37 @@ I64.enc(base.ctz.i32, *r.urm.rex(0xf3, 0x0f, 0xbc), isap=cfg.use_bmi1) I64.enc(base.ctz.i32, *r.urm(0xf3, 0x0f, 0xbc), isap=cfg.use_bmi1) # Loads and stores. -I32.enc(base.store.i32.i32, *r.st(0x89)) -I32.enc(base.store.i32.i32, *r.stDisp8(0x89)) -I32.enc(base.store.i32.i32, *r.stDisp32(0x89)) +I32.enc(base.store.i32.any, *r.st(0x89)) +I32.enc(base.store.i32.any, *r.stDisp8(0x89)) +I32.enc(base.store.i32.any, *r.stDisp32(0x89)) -I32.enc(base.istore16.i32.i32, *r.st(0x66, 0x89)) -I32.enc(base.istore16.i32.i32, *r.stDisp8(0x66, 0x89)) -I32.enc(base.istore16.i32.i32, *r.stDisp32(0x66, 0x89)) +I32.enc(base.istore16.i32.any, *r.st(0x66, 0x89)) +I32.enc(base.istore16.i32.any, *r.stDisp8(0x66, 0x89)) +I32.enc(base.istore16.i32.any, *r.stDisp32(0x66, 0x89)) -I32.enc(base.istore8.i32.i32, *r.st_abcd(0x88)) -I32.enc(base.istore8.i32.i32, *r.stDisp8_abcd(0x88)) -I32.enc(base.istore8.i32.i32, *r.stDisp32_abcd(0x88)) +I32.enc(base.istore8.i32.any, *r.st_abcd(0x88)) +I32.enc(base.istore8.i32.any, *r.stDisp8_abcd(0x88)) +I32.enc(base.istore8.i32.any, *r.stDisp32_abcd(0x88)) -I32.enc(base.load.i32.i32, *r.ld(0x8b)) -I32.enc(base.load.i32.i32, *r.ldDisp8(0x8b)) -I32.enc(base.load.i32.i32, *r.ldDisp32(0x8b)) +I32.enc(base.load.i32.any, *r.ld(0x8b)) +I32.enc(base.load.i32.any, *r.ldDisp8(0x8b)) +I32.enc(base.load.i32.any, *r.ldDisp32(0x8b)) -I32.enc(base.uload16.i32.i32, *r.ld(0x0f, 0xb7)) -I32.enc(base.uload16.i32.i32, *r.ldDisp8(0x0f, 0xb7)) -I32.enc(base.uload16.i32.i32, *r.ldDisp32(0x0f, 0xb7)) +I32.enc(base.uload16.i32.any, *r.ld(0x0f, 0xb7)) +I32.enc(base.uload16.i32.any, *r.ldDisp8(0x0f, 0xb7)) +I32.enc(base.uload16.i32.any, *r.ldDisp32(0x0f, 0xb7)) -I32.enc(base.sload16.i32.i32, *r.ld(0x0f, 0xbf)) -I32.enc(base.sload16.i32.i32, *r.ldDisp8(0x0f, 0xbf)) -I32.enc(base.sload16.i32.i32, *r.ldDisp32(0x0f, 0xbf)) +I32.enc(base.sload16.i32.any, *r.ld(0x0f, 0xbf)) +I32.enc(base.sload16.i32.any, *r.ldDisp8(0x0f, 0xbf)) +I32.enc(base.sload16.i32.any, *r.ldDisp32(0x0f, 0xbf)) -I32.enc(base.uload8.i32.i32, *r.ld(0x0f, 0xb6)) -I32.enc(base.uload8.i32.i32, *r.ldDisp8(0x0f, 0xb6)) -I32.enc(base.uload8.i32.i32, *r.ldDisp32(0x0f, 0xb6)) +I32.enc(base.uload8.i32.any, *r.ld(0x0f, 0xb6)) +I32.enc(base.uload8.i32.any, *r.ldDisp8(0x0f, 0xb6)) +I32.enc(base.uload8.i32.any, *r.ldDisp32(0x0f, 0xb6)) -I32.enc(base.sload8.i32.i32, *r.ld(0x0f, 0xbe)) -I32.enc(base.sload8.i32.i32, *r.ldDisp8(0x0f, 0xbe)) -I32.enc(base.sload8.i32.i32, *r.ldDisp32(0x0f, 0xbe)) +I32.enc(base.sload8.i32.any, *r.ld(0x0f, 0xbe)) +I32.enc(base.sload8.i32.any, *r.ldDisp8(0x0f, 0xbe)) +I32.enc(base.sload8.i32.any, *r.ldDisp32(0x0f, 0xbe)) # # Call/return