summaryrefslogtreecommitdiff
path: root/ecomp-c/asm-i386.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-03-24 19:46:59 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-03-24 19:46:59 +0100
commita65e5418a7dd753577ffeb428e0230f0acbe1b00 (patch)
tree9a0a26dc1086924e013ac55601b013fc47199d65 /ecomp-c/asm-i386.c
parent1bfafbcf0751943fa4033e59133f8cd43cf66b65 (diff)
downloadcompilertests-a65e5418a7dd753577ffeb428e0230f0acbe1b00.tar.gz
compilertests-a65e5418a7dd753577ffeb428e0230f0acbe1b00.tar.bz2
implemented asm-i386, so it can handle test1.e for now
Diffstat (limited to 'ecomp-c/asm-i386.c')
-rw-r--r--ecomp-c/asm-i386.c85
1 files changed, 60 insertions, 25 deletions
diff --git a/ecomp-c/asm-i386.c b/ecomp-c/asm-i386.c
index 78cc5e6..40e8e97 100644
--- a/ecomp-c/asm-i386.c
+++ b/ecomp-c/asm-i386.c
@@ -683,6 +683,7 @@ static OpcodeInfo *parseOpcode( void )
if( strcmp( ident, "add" ) == 0 ) {
opcode_info->opcode = OPCODE_ADD;
opcode_info->nof_operands = 2;
+ opcode_info->incr = 2;
}
break;
case 'd':
@@ -693,42 +694,50 @@ static OpcodeInfo *parseOpcode( void )
} else if( strcmp( ident, "div" ) == 0 ) {
opcode_info->opcode = OPCODE_DIV;
opcode_info->nof_operands = 1;
+ opcode_info->incr = 2;
}
break;
case 'h':
if( strcmp( ident, "hlt" ) == 0 ) {
opcode_info->opcode = OPCODE_HLT;
opcode_info->nof_operands = 0;
+ opcode_info->incr = 1;
}
break;
case 'j':
if( strcmp( ident, "jmp" ) == 0 ) {
opcode_info->opcode = OPCODE_JMP;
opcode_info->nof_operands = 1;
+ opcode_info->incr = 5;
}
break;
case 'm':
if( strcmp( ident, "mov" ) == 0 ) {
opcode_info->opcode = OPCODE_MOV;
opcode_info->nof_operands = 2;
+ opcode_info->incr = 5;
} else if( strcmp( ident, "mul" ) == 0 ) {
opcode_info->opcode = OPCODE_MUL;
opcode_info->nof_operands = 1;
+ opcode_info->incr = 2;
}
break;
case 'p':
if( strcmp( ident, "push" ) == 0 ) {
opcode_info->opcode = OPCODE_PUSH;
opcode_info->nof_operands = 1;
+ opcode_info->incr = 1;
} else if( strcmp( ident, "pop" ) == 0 ) {
opcode_info->opcode = OPCODE_POP;
opcode_info->nof_operands = 1;
+ opcode_info->incr = 1;
}
break;
case 's':
if( strcmp( ident, "sub" ) == 0 ) {
opcode_info->opcode = OPCODE_SUB;
opcode_info->nof_operands = 2;
+ opcode_info->incr = 2;
}
break;
}
@@ -759,7 +768,10 @@ static void free_opcode_info( OpcodeInfo *opcode_info )
static int isRegister( char *s )
{
- if( ( strcmp( s, "eax" ) == 0 ) || ( strcmp( s, "ebx" ) == 0 ) ) {
+ if( ( strcmp( s, "eax" ) == 0 ) ||
+ ( strcmp( s, "ecx" ) == 0 ) ||
+ ( strcmp( s, "edx" ) == 0 ) ||
+ ( strcmp( s, "ebx" ) == 0 ) ) {
return 1;
}
return 0;
@@ -768,6 +780,8 @@ static int isRegister( char *s )
static Register getRegister( char *s )
{
if( strcmp( s, "eax" ) == 0 ) return REGISTER_EAX;
+ if( strcmp( s, "ecx" ) == 0 ) return REGISTER_ECX;
+ if( strcmp( s, "edx" ) == 0 ) return REGISTER_EDX;
if( strcmp( s, "ebx" ) == 0 ) return REGISTER_EBX;
return REGISTER_UNKNOWN;
}
@@ -1014,9 +1028,6 @@ static void print_opcodes( OpcodeInfo *opcode_info )
static void emit_opcode( OpcodeInfo *opcode_info )
{
-/*
- OperandInfo *operand;
-*/
switch( opcode_info->opcode ) {
case OPCODE_HLT:
Emit( "%c", 0xF4 );
@@ -1029,40 +1040,64 @@ static void emit_opcode( OpcodeInfo *opcode_info )
opcode_info->operand->next->type == OPERAND_ABSOLUTE ) {
Emit( "%c", 0xB8 | opcode_info->operand->reg );
Emit_double_little_endian( opcode_info->operand->next->num );
+ } else if( opcode_info->operand->type == OPERAND_MEMORY_INDIRECT &&
+ opcode_info->operand->next->type == OPERAND_REGISTER &&
+ opcode_info->operand->next->reg == REGISTER_EAX ) {
+ Emit( "%c", 0xA3 );
+ Emit_double_little_endian( opcode_info->operand->addr );
+ } else if( opcode_info->operand->type == OPERAND_REGISTER &&
+ opcode_info->operand->reg == REGISTER_EAX &&
+ opcode_info->operand->next->type == OPERAND_MEMORY_INDIRECT ) {
+ Emit( "%c", 0xA1 );
+ Emit_double_little_endian( opcode_info->operand->next->addr );
+ } else {
+ Abort( "Unsupported mov operand combination" );
}
break;
case OPCODE_PUSH:
+ if( opcode_info->operand->type == OPERAND_REGISTER ) {
+ Emit( "%c", 0x50 | opcode_info->operand->reg );
+ } else {
+ Abort( "push expects a register as argument" );
+ }
+ break;
case OPCODE_POP:
+ if( opcode_info->operand->type == OPERAND_REGISTER ) {
+ Emit( "%c", 0x58 | opcode_info->operand->reg );
+ } else {
+ Abort( "push expects a register as argument" );
+ }
+ break;
case OPCODE_ADD:
+ if( opcode_info->operand->type == OPERAND_REGISTER &&
+ opcode_info->operand->next->type == OPERAND_REGISTER ) {
+ Emit( "%c%c", 0x01, 0xC0 | ( opcode_info->operand->reg )
+ | ( opcode_info->operand->next->reg << 3 ) );
+ } else {
+ Abort( "Unsupported add" );
+ }
+ break;
case OPCODE_SUB:
+ if( opcode_info->operand->type == OPERAND_REGISTER &&
+ opcode_info->operand->next->type == OPERAND_REGISTER ) {
+ Emit( "%c%c", 0x29, 0xC0 | ( opcode_info->operand->reg )
+ | ( opcode_info->operand->next->reg << 3 ) );
+ } else {
+ Abort( "Unsupported add" );
+ }
+ break;
case OPCODE_MUL:
+ Emit( "%c%c", 0xF7, 0xE0 | opcode_info->operand->reg );
+ break;
case OPCODE_DIV:
+ Emit( "%c%c", 0xF7, 0xF0 | opcode_info->operand->reg );
+ break;
case OPCODE_JMP:
break;
default:
- Abort( "Non-implemented emit opcode '%s' when generating binary",
+ Abort( "Non-implemented opcode '%s' when generating binary",
opcodename[opcode_info->opcode] );
}
-
-/*
- fprintf( stderr, "%s", opcodename[opcode->opcode] );
- operand = opcode->operand;
- while( operand != NULL ) {
- switch( operand->type ) {
- case OPERAND_ABSOLUTE:
- fprintf( stderr, "%s$%X", indent, operand->num );
- break;
- case OPERAND_REGISTER:
- fprintf( stderr, "%s%s", indent, registername[operand->reg] );
- break;
- case OPERAND_MEMORY_DIRECT:
- fprintf( stderr, "%s%X", indent, operand->addr );
- break;
- case OPERAND_MEMORY_INDIRECT:
- fprintf( stderr, "%s[%X]", indent, operand->addr );
- break;
- }
-*/
}
static void emit_code( OpcodeInfo *opcode_info )