comparison modules/x86.tp @ 361:06dceff348ea

llcompile now has Hacky support for calling C functions using dl to lookup symbols and almost has support string constants
author Michael Pavone <pavone@retrodev.com>
date Thu, 23 Apr 2015 19:24:20 -0700
parents 023c29e1f595
children 7101ad443081
comparison
equal deleted inserted replaced
360:0b83f15e819d 361:06dceff348ea
136 mod_rm <- :reg rm { 136 mod_rm <- :reg rm {
137 mod_rm: reg rm withTail: [] 137 mod_rm: reg rm withTail: []
138 } 138 }
139 139
140 int_op:withTail <- :value size :tail { 140 int_op:withTail <- :value size :tail {
141 if: (not: (value isInteger?)) {
142 //label
143 //FIXME: Needs implementation
144 value <- 0
145 }
141 if: size >= dword { 146 if: size >= dword {
142 tail <- (uint8: (rshift: value by: 16u64)) | (uint8: (rshift: value by: 24u64)) | tail 147 tail <- (uint8: (rshift: value by: 16u64)) | (uint8: (rshift: value by: 24u64)) | tail
143 } 148 }
144 if: size >= word { 149 if: size >= word {
145 tail <- (uint8: (rshift: value by: 8u64)) | tail 150 tail <- (uint8: (rshift: value by: 8u64)) | tail
246 (inst map: :el { hex: el}) join: " " 251 (inst map: :el { hex: el}) join: " "
247 }) join: "\n" 252 }) join: "\n"
248 } 253 }
249 } 254 }
250 } 255 }
256
257 data <- :bytes {
258 #{
259 length <- { bytes byte_length }
260 flattenTo:at <- :dest :idx {
261 foreach: (range from: 0 to: length) :_ cidx {
262 dest set: idx + cidx (bytes byte: cidx)
263 }
264 idx + length
265 }
266 string <- {
267 "data: " . bytes
268 }
269 }
270 }
251 271
252 op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex { 272 op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex {
253 reg <- src 273 reg <- src
254 rm <- dst 274 rm <- dst
255 base <- if: (src isInteger?) { 275 base <- if: (src isInteger?) || (src label?) {
256 reg <- fakesrc 276 reg <- fakesrc
257 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size)) 277 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size))
258 } else: { 278 } else: {
259 if: (src register?) { 279 if: (src register?) {
260 (size_bit: normal size) | (mod_rm: src dst) 280 (size_bit: normal size) | (mod_rm: src dst)
319 pre append: inst 339 pre append: inst
320 } 340 }
321 multiInst: pre 341 multiInst: pre
322 } else: { 342 } else: {
323 myinst 343 myinst
344 }
345 }
346 _dlHandle <- option none
347 _getDLHandle <- {
348 _dlHandle value: :handle { handle } none: {
349 handle <- dl open: "" withFlags: (dl NOW)
350 _dlHandle <- option value: handle
351 handle
324 } 352 }
325 } 353 }
326 354
327 _jmprel <- :op jmpDest { 355 _jmprel <- :op jmpDest {
328 } 356 }
555 } 583 }
556 } 584 }
557 } 585 }
558 586
559 call <- :callDest { 587 call <- :callDest {
560 if: (callDest label?) { 588 if: (callDest isInteger?) {
561 #{ 589 #{
562 length <- { 5 } 590 length <- { 12 } //worst case
563 flattenTo:at <- :dest :idx { 591 flattenTo:at <- :dest :idx {
564 dest set: idx 0xE8u8 592 base <- (dest _buf_ptr) address
565 callDest withOffset: :off { 593 rel <- (callDest uint64) - (base + (idx uint64) + 5u64)
566 rel <- off - (idx + 5) 594 if: rel < 0x80000000u64 || rel >= 0xFFFFFFFF80000000u64 {
595 rel <- rel int64
596 dest set: idx 0xE8u8
567 dest set: (idx + 1) (uint8: rel) 597 dest set: (idx + 1) (uint8: rel)
568 dest set: (idx + 2) (uint8: (rshift: rel by: 8)) 598 dest set: (idx + 2) (uint8: (rshift: rel by: 8))
569 dest set: (idx + 3) (uint8: (rshift: rel by: 16)) 599 dest set: (idx + 3) (uint8: (rshift: rel by: 16))
570 dest set: (idx + 4) (uint8: (rshift: rel by: 24)) 600 dest set: (idx + 4) (uint8: (rshift: rel by: 24))
601 idx + 5
571 } else: { 602 } else: {
572 } 603 dst <- callDest uint64
573 idx + 5 604 dest set: idx 0x48u8 //REX size=quad
605 dest set: idx + 1 0xB8 //mov immed rax
606 dest set: idx + 2 (uint8: dst)
607 dest set: idx + 3 (uint8: (rshift: dst by: 8))
608 dest set: idx + 4 (uint8: (rshift: dst by: 16))
609 dest set: idx + 5 (uint8: (rshift: dst by: 24))
610 dest set: idx + 6 (uint8: (rshift: dst by: 32))
611 dest set: idx + 7 (uint8: (rshift: dst by: 40))
612 dest set: idx + 8 (uint8: (rshift: dst by: 48))
613 dest set: idx + 9 (uint8: (rshift: dst by: 56))
614 dest set: idx + 10 0xFFu8 //single EA op
615 dest set: idx + 11 0xd0u8 //call reg direct
616 idx + 12
617 }
618
574 } 619 }
575 string <- { 620 string <- {
576 "call " . callDest 621 "call " . callDest
577 } 622 }
578 } 623 }
579 } else: { 624 } else: {
580 inst: 0xFFu8 | (mod_rm: (opex: 2u8) callDest) 625 if: (callDest label?) {
626 #{
627 length <- { 5 }
628 flattenTo:at <- :dest :idx {
629 dest set: idx 0xE8u8
630 callDest withOffset: :off {
631 rel <- off - (idx + 5)
632 dest set: (idx + 1) (uint8: rel)
633 dest set: (idx + 2) (uint8: (rshift: rel by: 8))
634 dest set: (idx + 3) (uint8: (rshift: rel by: 16))
635 dest set: (idx + 4) (uint8: (rshift: rel by: 24))
636 } else: {
637 }
638 idx + 5
639 }
640 string <- {
641 "call " . callDest
642 }
643 }
644 } else: {
645 inst: 0xFFu8 | (mod_rm: (opex: 2u8) callDest)
646 }
581 } 647 }
582 } 648 }
583 649
584 setcc <- :cond dst { 650 setcc <- :cond dst {
585 src <- opex: 0u8 651 src <- opex: 0u8
787 } 853 }
788 854
789 toCall <- inst target 855 toCall <- inst target
790 if: (toCall isString?) { 856 if: (toCall isString?) {
791 //TODO: Handle call to undefined label 857 //TODO: Handle call to undefined label
792 toCall <- labels get: toCall else: { 858 toCall <- labels get: toCall else: {
793 print: "Could not find label " . toCall . "\nDefined labels:\n" 859 handle <- _getDLHandle:
794 foreach: labels :key _ { 860 address <- dl sym: toCall from: handle
795 print: "\t" . key . "\n" 861 if: address != 0u64 {
862 address
863 } else: {
864 print: "Could not find label " . toCall . "\nDefined labels:\n"
865 foreach: labels :key _ {
866 print: "\t" . key . "\n"
867 }
868 false
796 } 869 }
797 false
798 } 870 }
799 } 871 }
800 outarr append: (call: toCall) 872 outarr append: (call: toCall)
801 } 873 }
802 { 874 {
850 } 922 }
851 } 923 }
852 //bool 924 //bool
853 { 925 {
854 outarr append: (setcc: (mapcond: (inst cond)) (inst out)) 926 outarr append: (setcc: (mapcond: (inst cond)) (inst out))
927 }
928 //label
929 {
930 }
931 //data
932 {
933 outarr append: (data: (inst bytes))
855 } 934 }
856 ] 935 ]
857 print: "Opcode: " . (inst opcode) . "\n" 936 print: "Opcode: " . (inst opcode) . "\n"
858 fun <- opmap get: (inst opcode) 937 fun <- opmap get: (inst opcode)
859 fun: 938 fun: