# HG changeset patch # User Michael Pavone # Date 1430072174 25200 # Node ID e44f65abaf0ed42c229d99e4c37a78c06cb66ea3 # Parent d949fe826e04e84a73ffe6840aa802c9691f5382 Support labels in non-branch instructions. String literals now work and so does the llhello sample diff -r d949fe826e04 -r e44f65abaf0e modules/x86.tp --- a/modules/x86.tp Sat Apr 25 20:56:02 2015 -0700 +++ b/modules/x86.tp Sun Apr 26 11:16:14 2015 -0700 @@ -61,6 +61,7 @@ _size <- :s { #{ num <- { s } + bytes <- { lshift: 1 by: s } = <- :other { s = (other num) } @@ -234,6 +235,25 @@ string <- { (ilist map: :el { hex: el}) join: " "} } } + + labelinst <- :prefix label size { + _length <- (prefix length) + (size bytes) + #{ + length <- { _length } + flattenTo:at <- :dest :idx { + label withOffset: :off { + writeBytes <- :idx byte { + dest set: idx byte + idx + 1 + } + idx <- prefix fold: idx with: writeBytes + (int_op64: ((dest _buf_ptr) address) + (off uint64) size) fold: idx with: writeBytes + } else: { + idx + _length + } + } + } + } multiInst <- :instarr { #{ length <- { @@ -274,19 +294,27 @@ op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex { reg <- src rm <- dst - base <- if: (src isInteger?) || (src label?) { - reg <- fakesrc - (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size)) + if: (not: (src isInteger?)) && (src label?) { + //most instructions only support 32-bit immediates + if: size = qword { + size <- dword + } + labelinst: (prefix: reg rm size withInstruction: (size_bit: immed size) | (mod_rm: (opex: myopex) dst)) src size } else: { - if: (src register?) { - (size_bit: normal size) | (mod_rm: src dst) + base <- if: (src isInteger?) { + reg <- fakesrc + (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size)) } else: { - reg <- dst - rm <- src - (size_bit: normal or 0x02u8 size) | (mod_rm: dst src) + if: (src register?) { + (size_bit: normal size) | (mod_rm: src dst) + } else: { + reg <- dst + rm <- src + (size_bit: normal or 0x02u8 size) | (mod_rm: dst src) + } } + inst: (prefix: reg rm size withInstruction: base) } - inst: (prefix: reg rm size withInstruction: base) } op:withCode:withImmed:withImmedRax:withOpEx:withByteExtend <- :src dst size :normal :immed :immedRax :myopex :byteExt { @@ -440,7 +468,12 @@ base <- opval or (dst reg) | (int_op64: src size) inst: (prefix: fakesrc rm size withInstruction: base) } else: { - op: src dst size withCode: 0x88u8 withImmed: 0xC6u8 withOpEx: 0u8 + if: (src label?) && (dst register?) { + opval <- if: size = byte { 0xB0u8 } else: { 0xB8u8 } + labelinst: (prefix: fakesrc rm size withInstruction: [opval or (dst reg)]) src size + } else: { + op: src dst size withCode: 0x88u8 withImmed: 0xC6u8 withOpEx: 0u8 + } } }