Mercurial > repos > tabletprog
comparison modules/x86.tp @ 204:a8dffa4d4b54
Add support for the rest of the instructions currently defined in the il module in the x86 module
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 28 Aug 2013 21:50:22 -0700 |
parents | 56b2100d9fff |
children | f987bb2a1911 |
comparison
equal
deleted
inserted
replaced
203:56b2100d9fff | 204:a8dffa4d4b54 |
---|---|
226 idx + 1 | 226 idx + 1 |
227 } | 227 } |
228 } | 228 } |
229 } | 229 } |
230 } | 230 } |
231 multiInst <- :instarr { | |
232 #{ | |
233 length <- { | |
234 instarr fold: 0 with: :acc inst { | |
235 acc + (inst length) | |
236 } | |
237 } | |
238 flattenTo:at <- :dest :idx { | |
239 instarr fold: idx with: :idx inst { | |
240 inst flattenTo: dest at: idx | |
241 } | |
242 } | |
243 } | |
244 } | |
231 | 245 |
232 op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex { | 246 op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex { |
233 reg <- src | 247 reg <- src |
234 rm <- dst | 248 rm <- dst |
235 base <- if: (src isInteger?) { | 249 base <- if: (src isInteger?) { |
262 } | 276 } |
263 } | 277 } |
264 inst: (prefix: reg rm size withInstruction: base) | 278 inst: (prefix: reg rm size withInstruction: base) |
265 } else: { | 279 } else: { |
266 op: src dst size withCode: normal withImmed: immed withOpEx: myopex | 280 op: src dst size withCode: normal withImmed: immed withOpEx: myopex |
281 } | |
282 } | |
283 | |
284 shiftRot:withOpEx <- :amount dst size :myopex { | |
285 opcode <- 0u8 | |
286 tail <- [] | |
287 pre <- #[] | |
288 post <- #[] | |
289 base <- if: (amount isInteger?) { | |
290 if: amount = 1 { | |
291 opcode <- 0xD0u8 | |
292 } else: { | |
293 opcode <- 0xC0u8 | |
294 tail <- [uint8: amount] | |
295 } | |
296 } else: { | |
297 opcode <- 0xD2u8 | |
298 if: (not: _rcx = amount) { | |
299 pre <- #[ | |
300 x86 push: _rcx | |
301 x86 mov: amount _rcx byte | |
302 ] | |
303 post <- #[ | |
304 x86 pop: _rcx | |
305 ] | |
306 } | |
307 } | |
308 bytes <- prefix: fakesrc dst withInstruction: (size_bit: 0xC0u8 size) | (mod_rm: (opex: myopex) dst withTail: tail) | |
309 myinst <- inst: bytes | |
310 if: (pre length) > 0 { | |
311 pre append: myinst | |
312 foreach: post :_ inst { | |
313 pre append: inst | |
314 } | |
315 multiInst: pre | |
316 } else: { | |
317 myinst | |
267 } | 318 } |
268 } | 319 } |
269 | 320 |
270 _jmprel <- :op jmpDest { | 321 _jmprel <- :op jmpDest { |
271 } | 322 } |
328 | 379 |
329 sub <- :src dst size { | 380 sub <- :src dst size { |
330 op: src dst size withCode: 0x28u8 withImmed: 0x80u8 withImmedRax: 0x2Cu8 withOpEx: 5u8 withByteExtend: 0x83u8 | 381 op: src dst size withCode: 0x28u8 withImmed: 0x80u8 withImmedRax: 0x2Cu8 withOpEx: 5u8 withByteExtend: 0x83u8 |
331 } | 382 } |
332 | 383 |
384 cmp <- :src dst size { | |
385 op: src dst size withCode: 0x38u8 withImmed: 0x80u8 withImmedRax: 0x3Cu8 withOpEx: 7u8 withByteExtend: 0x83u8 | |
386 } | |
387 | |
388 and <- :src dst size { | |
389 op: src dst size withCode: 0x20u8 withImmed: 0x80u8 withImmedRax: 0x24u8 withOpEx: 4u8 withByteExtend: 0x83u8 | |
390 } | |
391 | |
392 or <- :src dst size { | |
393 op: src dst size withCode: 0x08u8 withImmed: 0x80u8 withImmedRax: 0x0Cu8 withOpEx: 1u8 withByteExtend: 0x83u8 | |
394 } | |
395 | |
396 xor <- :src dst size { | |
397 op: src dst size withCode: 0x30u8 withImmed: 0x80u8 withImmedRax: 0x34u8 withOpEx: 6u8 withByteExtend: 0x83u8 | |
398 } | |
399 | |
333 mov <- :src dst size { | 400 mov <- :src dst size { |
334 rm <- dst | 401 rm <- dst |
335 if: (src isInteger?) && (dst register?) { | 402 if: (src isInteger?) && (dst register?) { |
336 opval <- if: size = byte { 0xB0u8 } else: { 0xB8u8 } | 403 opval <- if: size = byte { 0xB0u8 } else: { 0xB8u8 } |
337 base <- opval or (dst reg) | (int_op64: src size) | 404 base <- opval or (dst reg) | (int_op64: src size) |
338 inst: (prefix: fakesrc rm size withInstruction: base) | 405 inst: (prefix: fakesrc rm size withInstruction: base) |
339 } else: { | 406 } else: { |
340 op: src dst size withCode: 0x88u8 withImmed: 0xC6u8 withOpEx: 0u8 | 407 op: src dst size withCode: 0x88u8 withImmed: 0xC6u8 withOpEx: 0u8 |
341 } | 408 } |
409 } | |
410 | |
411 shl <- :shift dst size { | |
412 shiftRot: shift dst size withOpEx: 4u8 | |
413 } | |
414 | |
415 shr <- :shift dst size { | |
416 shiftRot: shift dst size withOpEx: 5u8 | |
417 } | |
418 | |
419 sar <- :shift dst size { | |
420 shiftRot: shift dst size withOpEx: 7u8 | |
421 } | |
422 | |
423 rol <- :shift dst size { | |
424 shiftRot: shift dst size withOpEx: 0u8 | |
425 } | |
426 | |
427 ror <- :shift dst size { | |
428 shiftRot: shift dst size withOpEx: 1u8 | |
342 } | 429 } |
343 | 430 |
344 ret <- { inst: [ 0xC3u8 ] } | 431 ret <- { inst: [ 0xC3u8 ] } |
345 | 432 |
346 label <- { | 433 label <- { |
502 0x8Fu8 | (mod_rm: (opex: 0u8) dst) | 589 0x8Fu8 | (mod_rm: (opex: 0u8) dst) |
503 } | 590 } |
504 inst: (prefix: fakesrc dst d withInstruction: base) | 591 inst: (prefix: fakesrc dst d withInstruction: base) |
505 } | 592 } |
506 | 593 |
594 bnot <- :dst size { | |
595 base <- (size_bit: 0xF6u8 size) | (mod_rm: (opex: 2u8) dst) | |
596 inst: (prefix: fakesrc dst size withInstruction: base) | |
597 } | |
598 | |
507 //TODO: support multiple calling conventions | 599 //TODO: support multiple calling conventions |
508 regSource <- { | 600 regSource <- { |
509 _used <- 0 | 601 _used <- 0 |
510 _usedAllTime <- 0 | 602 _usedAllTime <- 0 |
511 _nextStackOff <- 0 | 603 _nextStackOff <- 0 |
635 ] | 727 ] |
636 ccmap get: (ilcond cc) | 728 ccmap get: (ilcond cc) |
637 } | 729 } |
638 opmap <- #[ | 730 opmap <- #[ |
639 { outarr append: (add: (inst in) (inst out) (mapSize: (inst size))) } | 731 { outarr append: (add: (inst in) (inst out) (mapSize: (inst size))) } |
640 { } //and | 732 { outarr append: (and: (inst in) (inst out) (mapSize: (inst size))) } |
641 { } //or | 733 { outarr append: (or: (inst in) (inst out) (mapSize: (inst size))) } |
642 { } //xor | 734 { outarr append: (xor: (inst in) (inst out) (mapSize: (inst size))) } |
643 { outarr append: (sub: (inst in) (inst out) (mapSize: (inst size))) } | 735 { outarr append: (sub: (inst in) (inst out) (mapSize: (inst size))) } |
644 { } //cmp | 736 { outarr append: (cmp: (inst in) (inst out) (mapSize: (inst size))) } |
645 { } //not | 737 { outarr append: (bnot: (inst arg) (mapSize: (inst size))) } |
646 { } //sl | 738 { outarr append: (shl: (inst in) (inst out) (mapSize: (inst size))) } //sl |
647 { } //asr | 739 { outarr append: (sar: (inst in) (inst out) (mapSize: (inst size))) } //asr |
648 { } //lsr | 740 { outarr append: (shr: (inst in) (inst out) (mapSize: (inst size))) } //lsr |
649 { } //rol | 741 { outarr append: (rol: (inst in) (inst out) (mapSize: (inst size))) } |
650 { } //ror | 742 { outarr append: (ror: (inst in) (inst out) (mapSize: (inst size))) } |
651 { outarr append: (mov: (inst in) (inst out) (mapSize: (inst size))) } | 743 { outarr append: (mov: (inst in) (inst out) (mapSize: (inst size))) } |
652 { | 744 { |
653 //call | 745 //call |
654 arguments <- inst args | 746 arguments <- inst args |
655 cur <- (arguments length) - 1 | 747 cur <- (arguments length) - 1 |