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