summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-06-15 19:54:01 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-06-15 19:54:01 +0200
commite5d9e83157f226ee6cad499f2a07b850cdcfc47c (patch)
treeafcf85578a6718005e8856ba384216acad2108e6
parent8d53bd7c238aa60cd8050a1972cfbfec338aebbd (diff)
downloadcompilertests-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.c23
-rw-r--r--ecomp-c/ec.c94
-rw-r--r--ecomp-c/test1.e1
-rw-r--r--ecomp-c/tests/asm-i386/mov.asm2
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