comparison modules/x86.tp @ 175:20b6041a8b23

Small refactor in x86 module. Added a few more instructions.
author Mike Pavone <pavone@retrodev.com>
date Thu, 22 Aug 2013 15:12:15 -0700
parents 8b5829372ad1
children 75aca5f87969
comparison
equal deleted inserted replaced
174:8b5829372ad1 175:20b6041a8b23
104 104
105 mod_rm <- :reg rm { 105 mod_rm <- :reg rm {
106 mod_rm: reg rm withTail: [] 106 mod_rm: reg rm withTail: []
107 } 107 }
108 108
109 int_op <- :value size { 109 int_op:withTail <- :value size :tail {
110 tail <- []
111 if: size >= dword { 110 if: size >= dword {
112 tail <- (uint8: (value rshift: 16)) | (uint8: (value rshift: 24)) | tail 111 tail <- (uint8: (value rshift: 16)) | (uint8: (value rshift: 24)) | tail
113 } 112 }
114 if: size >= word { 113 if: size >= word {
115 tail <- (uint8: (value rshift: 8)) | tail 114 tail <- (uint8: (value rshift: 8)) | tail
116 } 115 }
117 (uint8: value) | tail 116 (uint8: value) | tail
117 }
118 int_op <- :value size {
119 int_op: value size withTail: []
120 }
121 //used for mov instructions that support 64-bit immediate operands/offsets
122 int_op64 <- :value size {
123 tail <- []
124 if: size = qword {
125 tail <- (uint8: (value rshift: 32)) | (uint8: (value rshift: 40)) | (uint8: (value rshift: 48)) | (uint8: (value rshift: 56)) | tail
126 }
127 int_op: value size withTail: tail
118 } 128 }
119 129
120 prefix:withInstruction <- :reg rm size :inst { 130 prefix:withInstruction <- :reg rm size :inst {
121 if: size = word { 131 if: size = word {
122 inst <- 0x66u8 | inst 132 inst <- 0x66u8 | inst
147 _ah <- upper: 4u8 157 _ah <- upper: 4u8
148 _ch <- upper: 5u8 158 _ch <- upper: 5u8
149 _dh <- upper: 6u8 159 _dh <- upper: 6u8
150 _bh <- upper: 7u8 160 _bh <- upper: 7u8
151 161
152 op:withCode:withImmed:withImmedRax:withOpEx:withByteExtend <- :src dst size :normal :immed :immedRax :myopex :byteExt { 162 op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex {
153 reg <- src 163 reg <- src
154 rm <- dst 164 rm <- dst
155 base <- if: (src isInteger?) { 165 base <- if: (src isInteger?) {
156 reg <- fakesrc 166 reg <- fakesrc
157 if: size > byte && (((src signed?) && src < 128 && src >= -128) || ((not: (src signed?)) && src < 256)) { 167 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size))
158 0x83u8 | (mod_rm: (opex: myopex) dst withTail: [(uint8: src)])
159 } else: {
160 if: dst = _rax {
161 (size_bit: immedRax size) | (int_op: src size)
162 } else: {
163 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size))
164 }
165 }
166 } else: { 168 } else: {
167 if: (src register?) { 169 if: (src register?) {
168 (size_bit: normal size) | (mod_rm: src dst) 170 (size_bit: normal size) | (mod_rm: src dst)
169 } else: { 171 } else: {
170 reg <- dst 172 reg <- dst
171 rm <- src 173 rm <- src
172 (size_bit: normal or 0x02u8 size) | (mod_rm: dst src) 174 (size_bit: normal or 0x02u8 size) | (mod_rm: dst src)
173 } 175 }
174 } 176 }
175 prefix: reg rm size withInstruction: base 177 prefix: reg rm size withInstruction: base
178 }
179
180 op:withCode:withImmed:withImmedRax:withOpEx:withByteExtend <- :src dst size :normal :immed :immedRax :myopex :byteExt {
181 reg <- src
182 rm <- dst
183 if: (src isInteger?) {
184 reg <- fakesrc
185 base <- if: size > byte && (((src signed?) && src < 128 && src >= -128) || ((not: (src signed?)) && src < 256)) {
186 0x83u8 | (mod_rm: (opex: myopex) dst withTail: [(uint8: src)])
187 } else: {
188 if: dst = _rax {
189 (size_bit: immedRax size) | (int_op: src size)
190 } else: {
191 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size))
192 }
193 }
194 prefix: reg rm size withInstruction: base
195 } else: {
196 op: src dst size withCode: normal withImmed: immed withOpEx: myopex
197 }
198
176 } 199 }
177 200
178 #{ 201 #{
179 rax <- { _rax } 202 rax <- { _rax }
180 rcx <- { _rcx } 203 rcx <- { _rcx }
204 227
205 add <- :src dst size { 228 add <- :src dst size {
206 op: src dst size withCode: 0u8 withImmed: 0x80u8 withImmedRax: 0x04u8 withOpEx: 0u8 withByteExtend: 0x83u8 229 op: src dst size withCode: 0u8 withImmed: 0x80u8 withImmedRax: 0x04u8 withOpEx: 0u8 withByteExtend: 0x83u8
207 } 230 }
208 231
232 sub <- :src dst size {
233 op: src dst size withCode: 0x28u8 withImmed: 0x80u8 withImmedRax: 0x2Cu8 withOpEx: 5u8 withByteExtend: 0x83u8
234 }
235
236 mov <- :src dst size {
237 reg <- src
238 rm <- dst
239 if: (src isInteger?) && (dst register?) {
240 opval <- if: size = byte { 0xB0u8 } else: { 0xB8u8 }
241 base <- opval | (int_op64: src size)
242 prefix: fakesrc rm size withInstruction: base
243 } else: {
244 op: src dst size withCode: 0x88u8 withImmed: 0xC6u8 withOpEx: 0u8
245 }
246 }
247
248 ret <- { [ 0xC3u8 ] }
249
209 250
210 main <- { 251 main <- {
211 print: ((add: rax r8 b) map: :el { hex: el }) 252 print: ((add: rax r8 b) map: :el { hex: el })
212 print: "\n" 253 print: "\n"
213 print: ((add: r9 rdx w) map: :el { hex: el }) 254 print: ((add: r9 rdx w) map: :el { hex: el })