1package operand 2 3import ( 4 "math" 5 "reflect" 6 "runtime" 7 "testing" 8 9 "github.com/mmcloughlin/avo/reg" 10) 11 12func TestChecks(t *testing.T) { 13 cases := []struct { 14 Predicate func(Op) bool 15 Operand Op 16 Expect bool 17 }{ 18 // Immediates 19 {Is1, Imm(1), true}, 20 {Is1, Imm(23), false}, 21 22 {Is3, Imm(3), true}, 23 {Is3, Imm(23), false}, 24 25 {IsIMM2U, Imm(3), true}, 26 {IsIMM2U, Imm(4), false}, 27 28 {IsIMM8, Imm(255), true}, 29 {IsIMM8, Imm(256), false}, 30 31 {IsIMM16, Imm((1 << 16) - 1), true}, 32 {IsIMM16, Imm(1 << 16), false}, 33 34 {IsIMM32, Imm((1 << 32) - 1), true}, 35 {IsIMM32, Imm(1 << 32), false}, 36 37 {IsIMM64, Imm((1 << 64) - 1), true}, 38 39 // Specific registers 40 {IsAL, reg.AL, true}, 41 {IsAL, reg.CL, false}, 42 43 {IsCL, reg.CL, true}, 44 {IsCL, reg.DH, false}, 45 46 {IsAX, reg.AX, true}, 47 {IsAX, reg.DX, false}, 48 49 {IsEAX, reg.EAX, true}, 50 {IsEAX, reg.ECX, false}, 51 52 {IsRAX, reg.RAX, true}, 53 {IsRAX, reg.R13, false}, 54 55 // General-purpose registers 56 {IsR8, reg.AL, true}, 57 {IsR8, reg.CH, true}, 58 {IsR8, reg.EAX, false}, 59 60 {IsR16, reg.DX, true}, 61 {IsR16, reg.R10W, true}, 62 {IsR16, reg.R10B, false}, 63 64 {IsR32, reg.EBP, true}, 65 {IsR32, reg.R14L, true}, 66 {IsR32, reg.R8, false}, 67 68 {IsR64, reg.RDX, true}, 69 {IsR64, reg.R10, true}, 70 {IsR64, reg.EBX, false}, 71 72 // Vector registers 73 {IsXMM0, reg.X0, true}, 74 {IsXMM0, reg.X13, false}, 75 {IsXMM0, reg.Y3, false}, 76 77 {IsXMM, reg.X0, true}, 78 {IsXMM, reg.X13, true}, 79 {IsXMM, reg.Y3, false}, 80 {IsXMM, reg.Z23, false}, 81 82 {IsYMM, reg.Y0, true}, 83 {IsYMM, reg.Y13, true}, 84 {IsYMM, reg.Y31, true}, 85 {IsYMM, reg.X3, false}, 86 {IsYMM, reg.Z3, false}, 87 88 // Pseudo registers. 89 {IsPseudo, reg.FramePointer, true}, 90 {IsPseudo, reg.ProgramCounter, true}, 91 {IsPseudo, reg.StaticBase, true}, 92 {IsPseudo, reg.StackPointer, true}, 93 {IsPseudo, reg.ECX, false}, 94 {IsPseudo, reg.X9, false}, 95 96 // Memory operands 97 {IsM, Mem{Base: reg.CX}, true}, 98 {IsM, Mem{Base: reg.ECX}, true}, 99 {IsM, Mem{Base: reg.RCX}, true}, 100 {IsM, Mem{Base: reg.X0}, false}, 101 102 {IsM8, Mem{Disp: 8, Base: reg.CL}, true}, 103 {IsM8, Mem{Disp: 8, Base: reg.CL, Index: reg.AH, Scale: 2}, true}, 104 {IsM8, Mem{Disp: 8, Base: reg.X0, Index: reg.AH, Scale: 2}, false}, 105 {IsM8, Mem{Disp: 8, Base: reg.CL, Index: reg.X0, Scale: 2}, false}, 106 107 {IsM16, Mem{Disp: 4, Base: reg.DX}, true}, 108 {IsM16, Mem{Disp: 4, Base: reg.R13W, Index: reg.R8W, Scale: 2}, true}, 109 {IsM16, Mem{Disp: 4, Base: reg.X0, Index: reg.R8W, Scale: 2}, false}, 110 {IsM16, Mem{Disp: 4, Base: reg.R13W, Index: reg.X0, Scale: 2}, false}, 111 112 {IsM32, Mem{Base: reg.R13L, Index: reg.EBX, Scale: 2}, true}, 113 {IsM32, Mem{Base: reg.X0}, false}, 114 115 {IsM64, Mem{Base: reg.RBX, Index: reg.R12, Scale: 2}, true}, 116 {IsM64, Mem{Base: reg.X0}, false}, 117 118 {IsM128, Mem{Base: reg.RBX, Index: reg.R12, Scale: 2}, true}, 119 {IsM128, Mem{Base: reg.X0}, false}, 120 121 {IsM256, Mem{Base: reg.RBX, Index: reg.R12, Scale: 2}, true}, 122 {IsM256, Mem{Base: reg.X0}, false}, 123 124 // Argument references (special cases of memory operands) 125 {IsM, NewParamAddr("foo", 4), true}, 126 {IsM8, NewParamAddr("foo", 4), true}, 127 {IsM16, NewParamAddr("foo", 4), true}, 128 {IsM32, NewParamAddr("foo", 4), true}, 129 {IsM64, NewParamAddr("foo", 4), true}, 130 131 // Vector memory operands 132 {IsVM32X, Mem{Base: reg.R14, Index: reg.X11}, true}, 133 {IsVM32X, Mem{Base: reg.R14L, Index: reg.X11}, false}, 134 {IsVM32X, Mem{Base: reg.R14, Index: reg.Y11}, false}, 135 136 {IsVM64X, Mem{Base: reg.R14, Index: reg.X11}, true}, 137 {IsVM64X, Mem{Base: reg.R14L, Index: reg.X11}, false}, 138 {IsVM64X, Mem{Base: reg.R14, Index: reg.Y11}, false}, 139 140 {IsVM32Y, Mem{Base: reg.R9, Index: reg.Y11}, true}, 141 {IsVM32Y, Mem{Base: reg.R11L, Index: reg.Y11}, false}, 142 {IsVM32Y, Mem{Base: reg.R8, Index: reg.Z11}, false}, 143 144 {IsVM64Y, Mem{Base: reg.R9, Index: reg.Y11}, true}, 145 {IsVM64Y, Mem{Base: reg.R11L, Index: reg.Y11}, false}, 146 {IsVM64Y, Mem{Base: reg.R8, Index: reg.Z11}, false}, 147 148 // Relative operands 149 {IsREL8, Rel(math.MinInt8), true}, 150 {IsREL8, Rel(math.MaxInt8), true}, 151 {IsREL8, Rel(math.MinInt8 - 1), false}, 152 {IsREL8, Rel(math.MaxInt8 + 1), false}, 153 {IsREL8, reg.R9B, false}, 154 155 {IsREL32, Rel(math.MinInt32), true}, 156 {IsREL32, Rel(math.MaxInt32), true}, 157 {IsREL32, LabelRef("label"), true}, 158 {IsREL32, reg.R9L, false}, 159 } 160 161 for _, c := range cases { 162 if c.Predicate(c.Operand) != c.Expect { 163 t.Errorf("%s( %#v ) != %v", funcname(c.Predicate), c.Operand, c.Expect) 164 } 165 } 166} 167 168func funcname(f interface{}) string { 169 return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name() 170} 171