Mercurial > repos > tabletprog
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 |