changeset 181:f188723c15b4

Add call instruction to x86 module
author Mike Pavone <pavone@retrodev.com>
date Sat, 24 Aug 2013 16:21:42 -0700
parents 270d31c6c4cd
children ab7c142090a0
files modules/x86.tp
diffstat 1 files changed, 32 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/modules/x86.tp	Sat Aug 24 15:08:00 2013 -0700
+++ b/modules/x86.tp	Sat Aug 24 16:21:42 2013 -0700
@@ -10,7 +10,7 @@
 			validforSize? <- :size { true }
 			isInteger? <- { false }
 			register? <- { true }
-			localLabel? <- { false }
+			label? <- { false }
 			upper? <- { true }
 			needsRex? <- { regnum >= 8u8 }
 			rexBitReg <- {
@@ -44,7 +44,7 @@
 			}
 			isInteger? <- { false }
 			register? <- { true }
-			localLabel? <- { false }
+			label? <- { false }
 			upper? <- { true }
 			needsRex? <- { false }
 			= <- :other {
@@ -267,16 +267,18 @@
 
 		label <- {
 			_offset <- -1
+			_address <- 0u64
 			_forwardRefs <- #[]
 			#{
 				length <- { 0 }
 				hasOffset? <- { _offset >= 0 }
 				offset <- { _offset }
 				register? <- { false }
-				localLabel? <- { true }
+				label? <- { true }
 				flattenTo:at <- :dest :idx {
 					if: (not: hasOffset?) {
 						_offset <- idx
+						_address <- dest addressAt: idx
 						foreach: _forwardRefs :idx fun {
 							fun: _offset
 						}
@@ -296,7 +298,7 @@
 		}
 
 		jmp <- :jmpDest {
-			if: (jmpDest localLabel?) {
+			if: (jmpDest label?) {
 				_size <- -1
 				#{
 					length <- { if: _size < 0 { 5 } else: { _size } }
@@ -344,10 +346,32 @@
 			}
 		}
 
+		call <- :callDest {
+			if: (callDest label?) {
+				#{
+					length <- { 5 }
+					flattenTo:at <- :dest :idx {
+						dest set: idx 0xE8u8
+						callDest withOffset: :off {
+							rel <- off - (idx + 5)
+							dest set: (idx + 1) (uint8: rel)
+							dest set: (idx + 2) (uint8: (rshift: rel by: 8))
+							dest set: (idx + 3) (uint8: (rshift: rel by: 16))
+							dest set: (idx + 4) (uint8: (rshift: rel by: 24))
+						} else: {
+						}
+						idx + 5
+					}
+				}
+			} else: {
+				inst: 0xFFu8 | (mod_rm: (opex: 2u8) callDest)
+			}
+		}
 
 		main <- {
 			foo <- label:
 			bar <- label:
+			baz <- label:
 			prog <- #[
 				mov: rdi rax q
 				sub: 1 rdi q
@@ -357,7 +381,11 @@
 				ret:
 				bar
 				sub: 13 rax q
+				call: baz
 				jmp: foo
+				baz
+				add: 1 rax q
+				ret:
 			]
 
 			ba <- bytearray executableFromBytes: prog