diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2020-06-15 19:54:01 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2020-06-15 19:54:01 +0200 |
commit | e5d9e83157f226ee6cad499f2a07b850cdcfc47c (patch) | |
tree | afcf85578a6718005e8856ba384216acad2108e6 | |
parent | 8d53bd7c238aa60cd8050a1972cfbfec338aebbd (diff) | |
download | compilertests-e5d9e83157f226ee6cad499f2a07b850cdcfc47c.tar.gz compilertests-e5d9e83157f226ee6cad499f2a07b850cdcfc47c.tar.bz2 |
asm-i386:
- added register indirect reads for expression evaluation with arrays
ec:
- started to add array expressions
-rw-r--r-- | ecomp-c/asm-i386.c | 23 | ||||
-rw-r--r-- | ecomp-c/ec.c | 94 | ||||
-rw-r--r-- | ecomp-c/test1.e | 1 | ||||
-rw-r--r-- | ecomp-c/tests/asm-i386/mov.asm | 2 |
4 files changed, 91 insertions, 29 deletions
diff --git a/ecomp-c/asm-i386.c b/ecomp-c/asm-i386.c index ab463a1..6f7fa5f 100644 --- a/ecomp-c/asm-i386.c +++ b/ecomp-c/asm-i386.c @@ -13,8 +13,10 @@ * A2 XX XX XX XX mov moffs8, al * A1 XX XX XX XX mov eax, moffs32 * A0 XX XX XX XX mov al, moffs8 - * 88 rr mov [r32], al * 89 rr mov [r32], eax + * 88 rr mov [r32], al + * 8A rr mov eax, [r32] + * 8B rr mov al, [r32] * 01 XX add r32, r32 * 29 XX sub r32, r32 * F7 E3 mul ebx @@ -1073,7 +1075,13 @@ static void parseOperands( OpcodeInfo *opcode_info ) opcode_info->operand->next->type == OPERAND_REGISTER && ( opcode_info->operand->next->reg == REGISTER_EAX || opcode_info->operand->next->reg == REGISTER_AL ) ) { - /* mov [ebx], eax, indirect addressing array/record elementss */ + /* mov [ebx], eax, indirect addressing array/record elements, write */ + opcode_info->size = 2; + } else if( opcode_info->operand->type == OPERAND_REGISTER && + opcode_info->operand->next->type == OPERAND_REGISTER_INDIRECT && + ( opcode_info->operand->reg == REGISTER_EAX || + opcode_info->operand->reg == REGISTER_AL ) ) { + /* mov eax, [ebx], indirect addressing array/record elements, read */ opcode_info->size = 2; } else { Abort( "Unsupported operand combination in 'mov'" ); @@ -1569,6 +1577,17 @@ static void emit_opcode( OpcodeInfo *opcode_info ) Emit( "%c", 0x88 ); } Emit( "%c", 0x03 ); + } else if( opcode_info->operand->type == OPERAND_REGISTER && + opcode_info->operand->next->type == OPERAND_REGISTER_INDIRECT && + opcode_info->operand->next->reg == REGISTER_EBX && + ( opcode_info->operand->reg == REGISTER_EAX || + opcode_info->operand->reg == REGISTER_AL ) ) { + if( opcode_info->operand->reg == REGISTER_EAX ) { + Emit( "%c", 0x8B ); + } else if( opcode_info->operand->reg == REGISTER_AL ) { + Emit( "%c", 0x8A ); + } + Emit( "%c", 0x03 ); } else { Abort( "Unhandled opcode generation case in 'mov'" ); } diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c index 737db92..8f40157 100644 --- a/ecomp-c/ec.c +++ b/ecomp-c/ec.c @@ -869,6 +869,20 @@ static void generate_expression_comment( ExpressionNode *node ) } } +static int get_size( Symbol *symbol ); + +static void EmitArrayDereference( Scope *scope, Symbol *array ) +{ + Emit( "pop eax\n" ); + Emit( "mov ebx, %d\n", get_size( array->type->type ) ); + Emit( "mul ebx\n" ); + Emit( "push eax\n" ); + Emit( "mov eax, %s\n", array->name ); + Emit( "pop ebx\n" ); + Emit( "add eax, ebx\n" ); + Emit( "push eax\n" ); +} + static void EmitConditionTest( Scope *scope, S_Symbol relation ) { char *jump_label1 = get_local_label( scope ); @@ -1082,9 +1096,9 @@ static void emit_expression_code( ExpressionNode *node, Scope *scope ) } } -static ExpressionNode *parseExpression( void ); +static ExpressionNode *parseExpression( Scope *scope ); -static ExpressionNode *parseFactor( void ) +static ExpressionNode *parseFactor( Scope *scope ) { Symbol *symbol; ExpressionNode *node = NULL; @@ -1128,16 +1142,49 @@ static ExpressionNode *parseFactor( void ) Abort( "'%s' is the name for a type and not a constant or variable as expected", ident ); } sym = getSym( ); + if( sym == S_lbracket ) { + ExpressionNode *expr; + + Expect( S_lbracket ); + if( symbol->type->class != SYMBOL_CLASS_ARRAY_TYPE ) { + Abort( "Dereferencing non-array '%s'", symbol->name ); + } + expr = parseExpression( scope ); + + /* HERE */ + emit_expression_code( expr, scope ); + + EmitArrayDereference( scope, symbol ); + +/* TODO: the right code, but in the wrong place as we should add + * array dereference as expression node into the AST and generate + * the dereferencing code much later when traversing the tree + * + if( !is_compatible_type( symbol->type->type, rhs->actual_type ) ) { + Abort( "Incompatible assignment of expression of type '%s' to variable '%s' of type '%s'", + rhs->actual_type->name, symbol->name, symbol->type->name ); + } + + emit_expression_code( rhs, scope ); + Emit( "pop eax\n" ); + + Emit( "pop ebx\n" ); +*/ + + free_expression_node( expr ); + + Expect( S_rbracket ); + } } else if( sym == S_lparen ) { sym = getSym( ); - node = parseExpression( ); + node = parseExpression( scope ); Expect( S_rparen ); } else if( sym == S_not ) { node = create_expression_node( ); node->type = EXPRESSION_NODE_TYPE_OP; node->op = sym; sym = getSym( ); - node->left = parseFactor( ); + node->left = parseFactor( scope ); node->actual_type = node->left->actual_type; } else { Abort( "Expected a literal, a variable or a constant." ); @@ -1146,11 +1193,11 @@ static ExpressionNode *parseFactor( void ) return node; } -static ExpressionNode *parseTerm( void ) +static ExpressionNode *parseTerm( Scope *scope ) { ExpressionNode *node, *tmp; - node = parseFactor( ); + node = parseFactor( scope ); while( sym == S_star || sym == S_div || sym == S_mod || sym == S_and ) { tmp = node; node = create_expression_node( ); @@ -1158,7 +1205,7 @@ static ExpressionNode *parseTerm( void ) node->op = sym; sym = getSym( ); node->left = tmp; - node->right = parseFactor( ); + node->right = parseFactor( scope ); if( node->left->actual_type == node->right->actual_type ) { node->actual_type = node->left->actual_type; @@ -1171,11 +1218,11 @@ static ExpressionNode *parseTerm( void ) return node; } -static ExpressionNode *parseSimpleExpression( void ) +static ExpressionNode *parseSimpleExpression( Scope *scope ) { ExpressionNode *node, *tmp; - node = parseTerm( ); + node = parseTerm( scope ); while( sym == S_plus || sym == S_minus || sym == S_or ) { tmp = node; node = create_expression_node( ); @@ -1183,7 +1230,7 @@ static ExpressionNode *parseSimpleExpression( void ) node->op = sym; sym = getSym( ); node->left = tmp; - node->right = parseTerm( ); + node->right = parseTerm( scope ); if( node->left->actual_type == node->right->actual_type ) { node->actual_type = node->left->actual_type; @@ -1210,11 +1257,11 @@ static int isRelationalOperator( S_Symbol sym ) } } -static ExpressionNode *parseExpression( void ) +static ExpressionNode *parseExpression( Scope *scope ) { ExpressionNode *node, *tmp; - node = parseSimpleExpression( ); + node = parseSimpleExpression( scope ); if( isRelationalOperator( sym ) ) { tmp = node; node = create_expression_node( ); @@ -1222,7 +1269,7 @@ static ExpressionNode *parseExpression( void ) node->op = sym; sym = getSym( ); node->left = tmp; - node->right = parseSimpleExpression( ); + node->right = parseSimpleExpression( scope ); if( node->left->actual_type == node->right->actual_type ) { node->actual_type = get_symbol( current_scope, "boolean" ); @@ -1255,7 +1302,7 @@ static void parseAssignment( Scope *scope ) if( sym == S_assign ) { Expect( S_assign ); - node = parseExpression( ); + node = parseExpression( scope ); Emit( "; LET %s <- ", symbol->name ); if( !is_compatible_type( symbol->type, node->actual_type ) ) { @@ -1287,7 +1334,7 @@ static void parseAssignment( Scope *scope ) Abort( "array index not allowed on '%s' (not an array)", symbol->name ); } Emit( "; LET %s[", symbol->name ); - lhs = parseExpression( ); + lhs = parseExpression( scope ); Expect( S_rbracket ); generate_expression_comment( lhs ); @@ -1295,22 +1342,15 @@ static void parseAssignment( Scope *scope ) Expect( S_assign ); - rhs = parseExpression( ); + rhs = parseExpression( scope ); generate_expression_comment( rhs ); Emit( "\n" ); emit_expression_code( lhs, scope ); - Emit( "pop eax\n" ); - Emit( "mov ebx, %d\n", get_size( symbol->type->type ) ); - Emit( "mul ebx\n" ); - Emit( "push eax\n" ); - Emit( "mov eax, %s\n", symbol->name ); - Emit( "pop ebx\n" ); - Emit( "add eax, ebx\n" ); - Emit( "push eax\n" ); - + EmitArrayDereference( scope, symbol ); + if( !is_compatible_type( symbol->type->type, rhs->actual_type ) ) { Abort( "Incompatible assignment of expression of type '%s' to variable '%s' of type '%s'", rhs->actual_type->name, symbol->name, symbol->type->name ); @@ -1345,7 +1385,7 @@ static void parseIfStatement( Scope *scope ) char *jump_label1 = get_local_label( scope ); char *jump_label2 = get_local_label( scope ); - node = parseExpression( ); + node = parseExpression( scope ); Emit( "; TEST " ); generate_expression_comment( node ); Emit( "\n" ); @@ -1376,7 +1416,7 @@ static void parseWhileStatement( Scope *scope ) char *jump_label1 = get_local_label( scope ); char *jump_label2 = get_local_label( scope ); - node = parseExpression( ); + node = parseExpression( scope ); Emit( "; WHILE " ); generate_expression_comment( node ); Emit( "\n" ); diff --git a/ecomp-c/test1.e b/ecomp-c/test1.e index 656d634..d88c3de 100644 --- a/ecomp-c/test1.e +++ b/ecomp-c/test1.e @@ -69,5 +69,6 @@ begin a1[i] := i; i := i + 1; end; + s2[a1[2]] := 'X'; //j := s2[1]; end diff --git a/ecomp-c/tests/asm-i386/mov.asm b/ecomp-c/tests/asm-i386/mov.asm index 2db4f1d..e45551f 100644 --- a/ecomp-c/tests/asm-i386/mov.asm +++ b/ecomp-c/tests/asm-i386/mov.asm @@ -9,6 +9,8 @@ push eax pop ebx mov [ebx], eax mov [ebx], al +mov eax, [ebx] +mov al, [ebx] hlt db "The" flag1: db $1 |