diff 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
line wrap: on
line diff
--- a/modules/x86.tp	Wed Aug 28 01:05:45 2013 -0700
+++ b/modules/x86.tp	Wed Aug 28 21:50:22 2013 -0700
@@ -228,6 +228,20 @@
 			}
 		}
 	}
+	multiInst <- :instarr {
+		#{
+			length <- {
+				instarr fold: 0 with: :acc inst {
+					acc + (inst length)
+				}
+			}
+			flattenTo:at <- :dest :idx {
+				instarr fold: idx with: :idx inst {
+					inst flattenTo: dest at: idx
+				}
+			}
+		}
+	}
 
 	op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex {
 		reg <- src
@@ -267,6 +281,43 @@
 		}
 	}
 
+	shiftRot:withOpEx <- :amount dst size :myopex {
+		opcode <- 0u8
+		tail <- []
+		pre <- #[]
+		post <- #[]
+		base <- if: (amount isInteger?) {
+			if: amount = 1 {
+				opcode <- 0xD0u8
+			} else: {
+				opcode <- 0xC0u8
+				tail <- [uint8: amount]
+			}
+		} else: {
+			opcode <- 0xD2u8
+			if: (not: _rcx = amount) {
+				pre <- #[
+					x86 push: _rcx
+					x86 mov: amount _rcx byte
+				]
+				post <- #[
+					x86 pop: _rcx
+				]
+			}
+		}
+		bytes <- prefix: fakesrc dst withInstruction: (size_bit: 0xC0u8 size) | (mod_rm: (opex: myopex) dst withTail: tail)
+		myinst <- inst: bytes
+		if: (pre length) > 0 {
+			pre append: myinst
+			foreach: post :_ inst {
+				pre append: inst
+			}
+			multiInst: pre
+		} else: {
+			myinst
+		}
+	}
+
 	_jmprel <- :op jmpDest {
 	}
 
@@ -330,6 +381,22 @@
 			op: src dst size withCode: 0x28u8 withImmed: 0x80u8 withImmedRax: 0x2Cu8 withOpEx: 5u8 withByteExtend: 0x83u8
 		}
 
+		cmp <- :src dst size {
+			op: src dst size withCode: 0x38u8 withImmed: 0x80u8 withImmedRax: 0x3Cu8 withOpEx: 7u8 withByteExtend: 0x83u8
+		}
+
+		and <- :src dst size {
+			op: src dst size withCode: 0x20u8 withImmed: 0x80u8 withImmedRax: 0x24u8 withOpEx: 4u8 withByteExtend: 0x83u8
+		}
+
+		or <- :src dst size {
+			op: src dst size withCode: 0x08u8 withImmed: 0x80u8 withImmedRax: 0x0Cu8 withOpEx: 1u8 withByteExtend: 0x83u8
+		}
+
+		xor <- :src dst size {
+			op: src dst size withCode: 0x30u8 withImmed: 0x80u8 withImmedRax: 0x34u8 withOpEx: 6u8 withByteExtend: 0x83u8
+		}
+
 		mov <- :src dst size {
 			rm <- dst
 			if: (src isInteger?) && (dst register?) {
@@ -341,6 +408,26 @@
 			}
 		}
 
+		shl <- :shift dst size {
+			shiftRot: shift dst size withOpEx: 4u8
+		}
+
+		shr <- :shift dst size {
+			shiftRot: shift dst size withOpEx: 5u8
+		}
+
+		sar <- :shift dst size {
+			shiftRot: shift dst size withOpEx: 7u8
+		}
+
+		rol <- :shift dst size {
+			shiftRot: shift dst size withOpEx: 0u8
+		}
+
+		ror <- :shift dst size {
+			shiftRot: shift dst size withOpEx: 1u8
+		}
+
 		ret <- { inst: [ 0xC3u8 ] }
 
 		label <- {
@@ -504,6 +591,11 @@
 			inst: (prefix: fakesrc dst d withInstruction: base)
 		}
 
+		bnot <- :dst size {
+			base <- (size_bit: 0xF6u8 size) | (mod_rm: (opex: 2u8) dst)
+			inst: (prefix: fakesrc dst size withInstruction: base)
+		}
+
 		//TODO: support multiple calling conventions
 		regSource <- {
 			_used <- 0
@@ -637,17 +729,17 @@
 			}
 			opmap <- #[
 				{ outarr append: (add: (inst in) (inst out) (mapSize: (inst size))) }
-				{ } //and
-				{ } //or
-				{ } //xor
+				{ outarr append: (and: (inst in) (inst out) (mapSize: (inst size))) }
+				{ outarr append: (or: (inst in) (inst out) (mapSize: (inst size))) }
+				{ outarr append: (xor: (inst in) (inst out) (mapSize: (inst size))) }
 				{ outarr append: (sub: (inst in) (inst out) (mapSize: (inst size))) }
-				{ } //cmp
-				{ } //not
-				{ } //sl
-				{ } //asr
-				{ } //lsr
-				{ } //rol
-				{ } //ror
+				{ outarr append: (cmp: (inst in) (inst out) (mapSize: (inst size))) }
+				{ outarr append: (bnot: (inst arg) (mapSize: (inst size))) }
+				{ outarr append: (shl: (inst in) (inst out) (mapSize: (inst size))) } //sl
+				{ outarr append: (sar: (inst in) (inst out) (mapSize: (inst size))) } //asr
+				{ outarr append: (shr: (inst in) (inst out) (mapSize: (inst size))) } //lsr
+				{ outarr append: (rol: (inst in) (inst out) (mapSize: (inst size))) }
+				{ outarr append: (ror: (inst in) (inst out) (mapSize: (inst size))) }
 				{ outarr append: (mov: (inst in) (inst out) (mapSize: (inst size))) }
 				{
 					//call