Mercurial > repos > tabletprog
comparison modules/x86.tp @ 175:20b6041a8b23
Small refactor in x86 module. Added a few more instructions.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 22 Aug 2013 15:12:15 -0700 |
parents | 8b5829372ad1 |
children | 75aca5f87969 |
comparison
equal
deleted
inserted
replaced
174:8b5829372ad1 | 175:20b6041a8b23 |
---|---|
104 | 104 |
105 mod_rm <- :reg rm { | 105 mod_rm <- :reg rm { |
106 mod_rm: reg rm withTail: [] | 106 mod_rm: reg rm withTail: [] |
107 } | 107 } |
108 | 108 |
109 int_op <- :value size { | 109 int_op:withTail <- :value size :tail { |
110 tail <- [] | |
111 if: size >= dword { | 110 if: size >= dword { |
112 tail <- (uint8: (value rshift: 16)) | (uint8: (value rshift: 24)) | tail | 111 tail <- (uint8: (value rshift: 16)) | (uint8: (value rshift: 24)) | tail |
113 } | 112 } |
114 if: size >= word { | 113 if: size >= word { |
115 tail <- (uint8: (value rshift: 8)) | tail | 114 tail <- (uint8: (value rshift: 8)) | tail |
116 } | 115 } |
117 (uint8: value) | tail | 116 (uint8: value) | tail |
117 } | |
118 int_op <- :value size { | |
119 int_op: value size withTail: [] | |
120 } | |
121 //used for mov instructions that support 64-bit immediate operands/offsets | |
122 int_op64 <- :value size { | |
123 tail <- [] | |
124 if: size = qword { | |
125 tail <- (uint8: (value rshift: 32)) | (uint8: (value rshift: 40)) | (uint8: (value rshift: 48)) | (uint8: (value rshift: 56)) | tail | |
126 } | |
127 int_op: value size withTail: tail | |
118 } | 128 } |
119 | 129 |
120 prefix:withInstruction <- :reg rm size :inst { | 130 prefix:withInstruction <- :reg rm size :inst { |
121 if: size = word { | 131 if: size = word { |
122 inst <- 0x66u8 | inst | 132 inst <- 0x66u8 | inst |
147 _ah <- upper: 4u8 | 157 _ah <- upper: 4u8 |
148 _ch <- upper: 5u8 | 158 _ch <- upper: 5u8 |
149 _dh <- upper: 6u8 | 159 _dh <- upper: 6u8 |
150 _bh <- upper: 7u8 | 160 _bh <- upper: 7u8 |
151 | 161 |
152 op:withCode:withImmed:withImmedRax:withOpEx:withByteExtend <- :src dst size :normal :immed :immedRax :myopex :byteExt { | 162 op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex { |
153 reg <- src | 163 reg <- src |
154 rm <- dst | 164 rm <- dst |
155 base <- if: (src isInteger?) { | 165 base <- if: (src isInteger?) { |
156 reg <- fakesrc | 166 reg <- fakesrc |
157 if: size > byte && (((src signed?) && src < 128 && src >= -128) || ((not: (src signed?)) && src < 256)) { | 167 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size)) |
158 0x83u8 | (mod_rm: (opex: myopex) dst withTail: [(uint8: src)]) | |
159 } else: { | |
160 if: dst = _rax { | |
161 (size_bit: immedRax size) | (int_op: src size) | |
162 } else: { | |
163 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size)) | |
164 } | |
165 } | |
166 } else: { | 168 } else: { |
167 if: (src register?) { | 169 if: (src register?) { |
168 (size_bit: normal size) | (mod_rm: src dst) | 170 (size_bit: normal size) | (mod_rm: src dst) |
169 } else: { | 171 } else: { |
170 reg <- dst | 172 reg <- dst |
171 rm <- src | 173 rm <- src |
172 (size_bit: normal or 0x02u8 size) | (mod_rm: dst src) | 174 (size_bit: normal or 0x02u8 size) | (mod_rm: dst src) |
173 } | 175 } |
174 } | 176 } |
175 prefix: reg rm size withInstruction: base | 177 prefix: reg rm size withInstruction: base |
178 } | |
179 | |
180 op:withCode:withImmed:withImmedRax:withOpEx:withByteExtend <- :src dst size :normal :immed :immedRax :myopex :byteExt { | |
181 reg <- src | |
182 rm <- dst | |
183 if: (src isInteger?) { | |
184 reg <- fakesrc | |
185 base <- if: size > byte && (((src signed?) && src < 128 && src >= -128) || ((not: (src signed?)) && src < 256)) { | |
186 0x83u8 | (mod_rm: (opex: myopex) dst withTail: [(uint8: src)]) | |
187 } else: { | |
188 if: dst = _rax { | |
189 (size_bit: immedRax size) | (int_op: src size) | |
190 } else: { | |
191 (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size)) | |
192 } | |
193 } | |
194 prefix: reg rm size withInstruction: base | |
195 } else: { | |
196 op: src dst size withCode: normal withImmed: immed withOpEx: myopex | |
197 } | |
198 | |
176 } | 199 } |
177 | 200 |
178 #{ | 201 #{ |
179 rax <- { _rax } | 202 rax <- { _rax } |
180 rcx <- { _rcx } | 203 rcx <- { _rcx } |
204 | 227 |
205 add <- :src dst size { | 228 add <- :src dst size { |
206 op: src dst size withCode: 0u8 withImmed: 0x80u8 withImmedRax: 0x04u8 withOpEx: 0u8 withByteExtend: 0x83u8 | 229 op: src dst size withCode: 0u8 withImmed: 0x80u8 withImmedRax: 0x04u8 withOpEx: 0u8 withByteExtend: 0x83u8 |
207 } | 230 } |
208 | 231 |
232 sub <- :src dst size { | |
233 op: src dst size withCode: 0x28u8 withImmed: 0x80u8 withImmedRax: 0x2Cu8 withOpEx: 5u8 withByteExtend: 0x83u8 | |
234 } | |
235 | |
236 mov <- :src dst size { | |
237 reg <- src | |
238 rm <- dst | |
239 if: (src isInteger?) && (dst register?) { | |
240 opval <- if: size = byte { 0xB0u8 } else: { 0xB8u8 } | |
241 base <- opval | (int_op64: src size) | |
242 prefix: fakesrc rm size withInstruction: base | |
243 } else: { | |
244 op: src dst size withCode: 0x88u8 withImmed: 0xC6u8 withOpEx: 0u8 | |
245 } | |
246 } | |
247 | |
248 ret <- { [ 0xC3u8 ] } | |
249 | |
209 | 250 |
210 main <- { | 251 main <- { |
211 print: ((add: rax r8 b) map: :el { hex: el }) | 252 print: ((add: rax r8 b) map: :el { hex: el }) |
212 print: "\n" | 253 print: "\n" |
213 print: ((add: r9 rdx w) map: :el { hex: el }) | 254 print: ((add: r9 rdx w) map: :el { hex: el }) |