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