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