comparison modules/x86.tp @ 364:e44f65abaf0e

Support labels in non-branch instructions. String literals now work and so does the llhello sample
author Michael Pavone <pavone@retrodev.com>
date Sun, 26 Apr 2015 11:16:14 -0700
parents d949fe826e04
children
comparison
equal deleted inserted replaced
363:d949fe826e04 364:e44f65abaf0e
59 rexBitRM <- { 0u8 } 59 rexBitRM <- { 0u8 }
60 } 60 }
61 _size <- :s { 61 _size <- :s {
62 #{ 62 #{
63 num <- { s } 63 num <- { s }
64 bytes <- { lshift: 1 by: s }
64 = <- :other { 65 = <- :other {
65 s = (other num) 66 s = (other num)
66 } 67 }
67 > <- :other { 68 > <- :other {
68 s > (other num) 69 s > (other num)
232 } 233 }
233 } 234 }
234 string <- { (ilist map: :el { hex: el}) join: " "} 235 string <- { (ilist map: :el { hex: el}) join: " "}
235 } 236 }
236 } 237 }
238
239 labelinst <- :prefix label size {
240 _length <- (prefix length) + (size bytes)
241 #{
242 length <- { _length }
243 flattenTo:at <- :dest :idx {
244 label withOffset: :off {
245 writeBytes <- :idx byte {
246 dest set: idx byte
247 idx + 1
248 }
249 idx <- prefix fold: idx with: writeBytes
250 (int_op64: ((dest _buf_ptr) address) + (off uint64) size) fold: idx with: writeBytes
251 } else: {
252 idx + _length
253 }
254 }
255 }
256 }
237 multiInst <- :instarr { 257 multiInst <- :instarr {
238 #{ 258 #{
239 length <- { 259 length <- {
240 instarr fold: 0 with: :acc inst { 260 instarr fold: 0 with: :acc inst {
241 acc + (inst length) 261 acc + (inst length)
272 } 292 }
273 293
274 op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex { 294 op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex {
275 reg <- src 295 reg <- src
276 rm <- dst 296 rm <- dst
277 base <- if: (src isInteger?) || (src label?) { 297 if: (not: (src isInteger?)) && (src label?) {
278 reg <- fakesrc 298 //most instructions only support 32-bit immediates
279 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size)) 299 if: size = qword {
300 size <- dword
301 }
302 labelinst: (prefix: reg rm size withInstruction: (size_bit: immed size) | (mod_rm: (opex: myopex) dst)) src size
280 } else: { 303 } else: {
281 if: (src register?) { 304 base <- if: (src isInteger?) {
282 (size_bit: normal size) | (mod_rm: src dst) 305 reg <- fakesrc
306 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size))
283 } else: { 307 } else: {
284 reg <- dst 308 if: (src register?) {
285 rm <- src 309 (size_bit: normal size) | (mod_rm: src dst)
286 (size_bit: normal or 0x02u8 size) | (mod_rm: dst src) 310 } else: {
287 } 311 reg <- dst
288 } 312 rm <- src
289 inst: (prefix: reg rm size withInstruction: base) 313 (size_bit: normal or 0x02u8 size) | (mod_rm: dst src)
314 }
315 }
316 inst: (prefix: reg rm size withInstruction: base)
317 }
290 } 318 }
291 319
292 op:withCode:withImmed:withImmedRax:withOpEx:withByteExtend <- :src dst size :normal :immed :immedRax :myopex :byteExt { 320 op:withCode:withImmed:withImmedRax:withOpEx:withByteExtend <- :src dst size :normal :immed :immedRax :myopex :byteExt {
293 reg <- src 321 reg <- src
294 rm <- dst 322 rm <- dst
438 if: (src isInteger?) && (dst register?) { 466 if: (src isInteger?) && (dst register?) {
439 opval <- if: size = byte { 0xB0u8 } else: { 0xB8u8 } 467 opval <- if: size = byte { 0xB0u8 } else: { 0xB8u8 }
440 base <- opval or (dst reg) | (int_op64: src size) 468 base <- opval or (dst reg) | (int_op64: src size)
441 inst: (prefix: fakesrc rm size withInstruction: base) 469 inst: (prefix: fakesrc rm size withInstruction: base)
442 } else: { 470 } else: {
443 op: src dst size withCode: 0x88u8 withImmed: 0xC6u8 withOpEx: 0u8 471 if: (src label?) && (dst register?) {
472 opval <- if: size = byte { 0xB0u8 } else: { 0xB8u8 }
473 labelinst: (prefix: fakesrc rm size withInstruction: [opval or (dst reg)]) src size
474 } else: {
475 op: src dst size withCode: 0x88u8 withImmed: 0xC6u8 withOpEx: 0u8
476 }
444 } 477 }
445 } 478 }
446 479
447 shl <- :shift dst size { 480 shl <- :shift dst size {
448 shiftRot: shift dst size withOpEx: 4u8 481 shiftRot: shift dst size withOpEx: 4u8