shithub: scc

Download patch

ref: 439629f3f58c21dd056721107e4dadb3b6e0482f
parent: d8b1cead3719c4c4254159f993fbc8222a2d2f09
author: zerous Naveen Narayanan <zerous@nocebo.space>
date: Sun Jan 6 08:56:59 EST 2019

[as/x86] Add more ADD instructions

ADDB	0x80
ADDW	0x66,0x01
ADDL	0x01

--- a/src/as/target/x86/ins.c
+++ b/src/as/target/x86/ins.c
@@ -259,19 +259,6 @@
 	}
 }
 
-void
-reg8_reg8(Op *op, Node **args)
-{
-	int src, dst;
-	char buf[2];
-
-	src = reg8toint(args[0]);
-	dst = reg8toint(args[1]);
-	buf[0] = op->bytes[0];
-	buf[1] = addrbyte(REG_MODE, src, dst);
-	emit(buf, 2);
-}
-
 static int
 reg16toint(Node *np)
 {
@@ -288,15 +275,73 @@
 	}
 }
 
+static int
+reg32toint(Node *np)
+{
+	switch (np->sym->value) {
+	case AREG_EAX: return 0;
+	case AREG_ECX: return 1;
+	case AREG_EDX: return 2;
+	case AREG_EBX: return 3;
+	case AREG_ESP: return 4;
+	case AREG_EBP: return 5;
+	case AREG_ESI: return 6;
+	case AREG_EDI: return 7;
+	default:	abort();
+	}
+}
+
 void
+reg8_reg8(Op *op, Node **args)
+{
+	int src, dst;
+	char buf[op->size];
+
+	src = reg8toint(args[0]);
+	dst = reg8toint(args[1]);
+	memcpy(buf, op->bytes, op->size - 1);
+	buf[op->size - 1] = addrbyte(REG_MODE, src, dst);
+	emit(buf, op->size);
+}
+
+void
+imm8_reg8(Op *op, Node **args)
+{
+	int src, dst;
+	char buf[op->size];
+
+	src = (*args)->sym->value;
+	dst = reg8toint(args[1]);
+	memcpy(buf, op->bytes, op->size - 2);
+	buf[op->size - 2] = addrbyte(REG_MODE, 0, dst);
+	buf[op->size - 1] = src;
+	emit(buf, op->size);
+}
+
+
+void
 reg16_reg16(Op *op, Node **args)
 {
 	int src, dst;
-	char buf[2];
+	char buf[op->size];
 
 	src = reg16toint(args[0]);
 	dst = reg16toint(args[1]);
-	buf[0] = op->bytes[0];
-	buf[1] = addrbyte(REG_MODE, src, dst);
-	emit(buf, 2);
+	memcpy(buf, op->bytes, op->size - 1);
+	buf[op->size - 1] = addrbyte(REG_MODE, src, dst);
+	emit(buf, op->size);
+}
+
+
+void
+reg32_reg32(Op *op, Node **args)
+{
+	int src, dst;
+	char buf[op->size];
+
+	src = reg32toint(args[0]);
+	dst = reg32toint(args[1]);
+	memcpy(buf, op->bytes, op->size - 1);
+	buf[op->size - 1] = addrbyte(REG_MODE, src, dst);
+	emit(buf, op->size);
 }
--- a/src/as/target/x86/proc.h
+++ b/src/as/target/x86/proc.h
@@ -146,11 +146,13 @@
 
 	AREG_MXCSR,
 
-	AREG_R8CLASS,   /* register class for 8 bit registers in i286 */
-	AREG_R16CLASS,   /* register class for 16 bit registers in i286 */
+	AREG_R8CLASS,	/* register class for 8 bit registers in i286 */
+	AREG_R16CLASS,	/* register class for 16 bit registers in i286,i386,amd64 */
+	AREG_R32CLASS,  /* register class for 32 bit registers in i386,amd64 */
 };
 
 enum class {
 	R8CLASS  = 1 << 0,
 	R16CLASS = 1 << 1,
+	R32CLASS = 1 << 2,
 };
--- a/src/as/target/x86/rules.dat
+++ b/src/as/target/x86/rules.dat
@@ -1,5 +1,6 @@
 reg8	AREG_R8CLASS
 reg16	AREG_R16CLASS
+reg32	AREG_R32CLASS
 imm8	AIMM8
 imm16	AIMM16
 imm32	AIMM32
--- a/src/as/target/x86/x86.dat
+++ b/src/as/target/x86/x86.dat
@@ -24,5 +24,8 @@
 
 
 # 8 bit arithmetic operations
-ADDB	reg8,reg8	2	0x00	reg8_reg8	I286,I386,AMD64
-ADDW	reg16,reg16	2 	0x01	reg16_reg16	I286,I386,AMD64
+ADDB	reg8,reg8	2	0x00		reg8_reg8	I286,I386,AMD64
+ADDB	imm8,reg8	3	0x80		imm8_reg8	I286,I386,AMD64
+ADDW	reg16,reg16	2	0x01		reg16_reg16	I286
+ADDW	reg16,reg16	3	0x66,0x01	reg16_reg16	I386,AMD64
+ADDL	reg32,reg32	2	0x01		reg32_reg32	I386,AMD64