scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit cb8cc84adef24f807f3c9ce4480329344c1aa474
parent c3bb0241d859c4845625ca2ba59c3c199417395f
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 18 May 2018 08:11:32 +0100

[as/286] Add reg8_reg8()

This function implements 8 bit register to register instructions.
It hasn't been tested, but it should work.

Diffstat:
Mas/target/x86/ins.c | 38++++++++++++++++++++++++++++++++++++++
Mas/target/x86/rules.dat | 4++--
Mas/target/x86/x86.dat | 2+-
3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/as/target/x86/ins.c b/as/target/x86/ins.c @@ -6,6 +6,15 @@ static char sccsid[] = "@(#) ./as/target/x86/ins.c"; #include "../../as.h" #include "proc.h" +#define addrbyte(mod, reg, rm) ((mod) << 6 | (reg) << 3 | (rm)) + +enum addr_mode { + MEM_MODE = 0, + MEM8_MODE = 1, + MEM16_MODE = 2, + REG_MODE = 3, +}; + static int getclass(Node *np) { @@ -221,3 +230,32 @@ Node * moperand(void) { } + +static int +reg8toint(Node *np) +{ + switch (np->sym->value) { + case AREG_AL: return 0; + case AREG_CL: return 1; + case AREG_DL: return 2; + case AREG_BL: return 3; + case AREG_AH: return 4; + case AREG_CH: return 5; + case AREG_DH: return 6; + case AREG_BH: return 7; + default: abort(); + } +} + +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); +} diff --git a/as/target/x86/rules.dat b/as/target/x86/rules.dat @@ -1,5 +1,5 @@ -reg8 AREG8 -reg16 AREG16 +reg8 AREG_R8CLASS +reg16 AREG_R16CLASS imm8 AIMM8 imm16 AIMM16 imm32 AIMM32 diff --git a/as/target/x86/x86.dat b/as/target/x86/x86.dat @@ -24,4 +24,4 @@ RET none 1 0xc3 noargs I286,I386,AMD64 # 8 bit arithmetic operations -#ADDB reg8,reg8 2 0x00,0xc0 reg2reg I286,I386,AMD64 +ADDB reg8,reg8 2 0x00 reg8_reg8 I286,I386,AMD64