diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2020-03-24 19:46:59 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2020-03-24 19:46:59 +0100 |
commit | a65e5418a7dd753577ffeb428e0230f0acbe1b00 (patch) | |
tree | 9a0a26dc1086924e013ac55601b013fc47199d65 /ecomp-c/asm-i386.c | |
parent | 1bfafbcf0751943fa4033e59133f8cd43cf66b65 (diff) | |
download | compilertests-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.c | 85 |
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 ) |