summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2021-09-27 19:34:16 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2021-09-27 19:34:16 +0200
commitc2bc809ca97bdebc8c70dd58a1c282c475a88557 (patch)
tree2b9ca1e8e1e0afc3b04a26c4cf3c44dc7187ccb8
parentf3181636d06af22d4828b4256c2a62d025fccb8a (diff)
downloadcompilertests-c2bc809ca97bdebc8c70dd58a1c282c475a88557.tar.gz
compilertests-c2bc809ca97bdebc8c70dd58a1c282c475a88557.tar.bz2
cc: added boolean expressions
-rw-r--r--ecomp-c/emul.c8
-rw-r--r--miniany/REQUIREMENTS2
-rw-r--r--miniany/cc.c158
-rw-r--r--miniany/test1.c12
-rw-r--r--miniany/test1.disasmust155
-rw-r--r--miniany/test1.hexmust36
6 files changed, 319 insertions, 52 deletions
diff --git a/ecomp-c/emul.c b/ecomp-c/emul.c
index c1d819f..348e54b 100644
--- a/ecomp-c/emul.c
+++ b/ecomp-c/emul.c
@@ -193,7 +193,7 @@ int main( int argc, char *argv[] )
printf( "Options:\n" );
printf( " -h show help\n" );
printf( " -v verbose output\n" );
- printf( " -d dump code and data read\n" );
+ printf( " -d dump code and data read (at start and at the end)\n" );
printf( " -t trace and print single stepts during emulation\n" );
exit( EXIT_SUCCESS );
default:
@@ -480,6 +480,12 @@ int main( int argc, char *argv[] )
}
}
+ if( dump ) {
+ dump_regs( uc );
+ dump_stack( uc );
+ dump_memory( uc, data_start, data_start + data_size );
+ }
+
if( verbose ) {
printf( "Done, executed %d instructions.\n", iteration );
}
diff --git a/miniany/REQUIREMENTS b/miniany/REQUIREMENTS
index 0472c1e..dd10d7e 100644
--- a/miniany/REQUIREMENTS
+++ b/miniany/REQUIREMENTS
@@ -115,5 +115,7 @@ TODO:
the language (no linker, no function calls etc. needed). OTOH we don't want to
have I/O as part of the language later, more be in the standard library.
Inline assembly in the generated code duplicates code with the putint in libc-freestanding.
+- error output is not on stderr, well, are we going to add stdout, stderr now
+ or do we write errors as sort of assembly comments?
diff --git a/miniany/cc.c b/miniany/cc.c
index 6f4f0a8..01472c9 100644
--- a/miniany/cc.c
+++ b/miniany/cc.c
@@ -13,7 +13,15 @@ enum {
S_STAR,
S_SLASH,
S_SEMICOLON,
+ S_LPAREN,
+ S_RPAREN,
+ S_ASSIGN,
S_EQUALS,
+ S_NOT_EQUALS,
+ S_LESS,
+ S_LESS_OR_EQUALS,
+ S_MORE,
+ S_MORE_OR_EQUALS,
S_INT = 10,
S_PUTINT,
S_IDENT = 20,
@@ -214,7 +222,43 @@ int getToken( struct Scanner *scanner )
scanner->token = S_SEMICOLON;
break;
case '=':
- scanner->token = S_EQUALS;
+ c = getChar( scanner );
+ if( c == '=' ) {
+ scanner->token = S_EQUALS;
+ } else {
+ pushBack( scanner );
+ scanner->token = S_ASSIGN;
+ }
+ break;
+ case '!':
+ c = getChar( scanner );
+ if( c == '=' ) {
+ scanner->token = S_NOT_EQUALS;
+ } else {
+ pushBack( scanner );
+ }
+ break;
+ case '<':
+ c = getChar( scanner );
+ if( c == '=' ) {
+ scanner->token = S_LESS_OR_EQUALS;
+ } else {
+ scanner->token = S_LESS;
+ }
+ break;
+ case '>':
+ c = getChar( scanner );
+ if( c == '=' ) {
+ scanner->token = S_MORE_OR_EQUALS;
+ } else {
+ scanner->token = S_MORE;
+ }
+ break;
+ case '(':
+ scanner->token = S_LPAREN;
+ break;
+ case ')':
+ scanner->token = S_RPAREN;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@@ -351,6 +395,12 @@ enum {
A_MULTIPLY,
A_DIVIDE,
A_ASSIGN,
+ A_EQUALS,
+ A_NOT_EQUALS,
+ A_LESS,
+ A_LESS_OR_EQUALS,
+ A_MORE,
+ A_MORE_OR_EQUALS,
A_ERR = 99
};
@@ -480,6 +530,32 @@ void putreg( struct Generator *generator, int reg )
putstring( generator->regName[reg] );
}
+void putlow8reg( struct Generator *generator, int reg )
+{
+ switch( reg ) {
+ case EAX:
+ putstring( "al" );
+ break;
+ case EBX:
+ putstring( "bl" );
+ break;
+ case ECX:
+ putstring( "cl" );
+ break;
+ case EDX:
+ putstring( "dl" );
+ break;
+ default:
+ scannerPrintErrorHeader( generator->scanner );
+ putstring( "error using low 8-bit subreguster of reguster '" );
+ putstring( generator->regName[reg] );
+ putstring( "'" );
+ putnl( );
+ exit( EXIT_FAILURE );
+ }
+}
+
+
void genAddGlob( struct Generator *generator, char *ident )
{
putstring( ident );
@@ -747,6 +823,26 @@ int genDiv( struct Generator *generator, int leftreg, int rightreg )
return reg;
}
+int genCompare( char *op, struct Generator *generator, int leftreg, int rightreg )
+{
+ putstring( "cmp " );
+ putreg( generator, leftreg );
+ putstring( ", " );
+ putreg( generator, rightreg );
+ putnl( );
+ putstring( op );
+ putchar( ' ' );
+ putlow8reg( generator, leftreg );
+ putnl( );
+ putstring( "and " );
+ putreg( generator, leftreg );
+ putstring( ", $FF" );
+ putnl( );
+ genFreeReg( generator, rightreg );
+
+ return leftreg;
+}
+
int generateFromAST( struct Generator *generator, struct ASTnode *node, int inreg )
{
int leftreg, rightreg, reg;
@@ -785,6 +881,24 @@ int generateFromAST( struct Generator *generator, struct ASTnode *node, int inre
case A_ASSIGN:
reg = inreg;
break;
+ case A_EQUALS:
+ reg = genCompare( "sete", generator, leftreg, rightreg );
+ break;
+ case A_NOT_EQUALS:
+ reg = genCompare( "setne", generator, leftreg, rightreg );
+ break;
+ case A_LESS_OR_EQUALS:
+ reg = genCompare( "setle", generator, leftreg, rightreg );
+ break;
+ case A_LESS:
+ reg = genCompare( "setl", generator, leftreg, rightreg );
+ break;
+ case A_MORE:
+ reg = genCompare( "setg", generator, leftreg, rightreg );
+ break;
+ case A_MORE_OR_EQUALS:
+ reg = genCompare( "setge", generator, leftreg, rightreg );
+ break;
default:
putint( node->op );
putstring( "?" );
@@ -897,6 +1011,30 @@ int parserTokenToOperator( struct Parser *parser, int token )
case S_MINUS:
op = A_SUBTRACT;
break;
+
+ case S_EQUALS:
+ op = A_EQUALS;
+ break;
+
+ case S_NOT_EQUALS:
+ op = A_NOT_EQUALS;
+ break;
+
+ case S_LESS:
+ op = A_LESS;
+ break;
+
+ case S_LESS_OR_EQUALS:
+ op = A_LESS_OR_EQUALS;
+ break;
+
+ case S_MORE:
+ op = A_MORE;
+ break;
+
+ case S_MORE_OR_EQUALS:
+ op = A_MORE_OR_EQUALS;
+ break;
default:
scannerPrintErrorHeader( parser->scanner );
@@ -915,6 +1053,18 @@ int parserOperatorPrecedence( struct Parser *parser, int operator )
precedence = 0;
switch( operator ) {
+ case A_LESS:
+ case A_LESS_OR_EQUALS:
+ case A_MORE:
+ case A_MORE_OR_EQUALS:
+ precedence = 4;
+ break;
+
+ case A_EQUALS:
+ case A_NOT_EQUALS:
+ precedence = 3;
+ break;
+
case A_MULTIPLY:
case A_DIVIDE:
precedence = 2;
@@ -973,7 +1123,7 @@ struct ASTnode *parseExpression( struct Parser *parser, int level )
}
parser->token = getToken( parser->scanner );
- if( parser->token == S_EOI || parser->token == S_SEMICOLON ) {
+ if( parser->token == S_EOI || parser->token == S_SEMICOLON || parser->token == S_RPAREN ) {
return left;
}
@@ -1032,7 +1182,7 @@ void parseAssignment( struct Compiler *compiler )
exit( EXIT_FAILURE );
}
right = createASTleafSym( A_LVIDENT, sym );
- parserExpect( parser, S_EQUALS, "=" );
+ parserExpect( parser, S_ASSIGN, "=" );
left = parseExpression( parser, 0 );
parserExpect( parser, S_SEMICOLON, ";" );
@@ -1049,7 +1199,9 @@ void parsePutint( struct Compiler *compiler )
parser = compiler->parser;
parserExpect( parser, S_PUTINT, "putint" );
+ parserExpect( parser, S_LPAREN, "(" );
node = parseExpression( parser, 0 );
+ parserExpect( parser, S_RPAREN, ")" );
parserExpect( parser, S_SEMICOLON, ";" );
generateFromAST( compiler->generator, node, NOREG );
putstring( "call putint" ); putnl( );
diff --git a/miniany/test1.c b/miniany/test1.c
index 1bfb8cf..63f0b49 100644
--- a/miniany/test1.c
+++ b/miniany/test1.c
@@ -5,8 +5,12 @@ int j;
int k;
i = 12+25/5-2*3; // 25/5 -> 5, 12+5 -> 17, 2*3 -> 6, 17-6 -> 11
-putint i;
+putint( i );
j = i/3+3*4; // 11 / 3 -> 3, 3*4 -> 12, 3+12 -> 15
-putint j;
-k = 0;
-putint k;
+putint( j );
+k = 7 == 7; putint( k );
+k = 8 != 7; putint( k );
+k = 8 <= 9; putint( k );
+k = 8 < 9; putint( k );
+k = 9 > 8; putint( k );
+k = 9 >= 8; putint( k );
diff --git a/miniany/test1.disasmust b/miniany/test1.disasmust
index 6f51f14..9bd0a4f 100644
--- a/miniany/test1.disasmust
+++ b/miniany/test1.disasmust
@@ -1,36 +1,119 @@
-01000000 B80C000000 mov eax,0xc
-01000005 BB19000000 mov ebx,0x19
-0100000A B905000000 mov ecx,0x5
-0100000F 50 push eax
-01000010 89D8 mov eax,ebx
-01000012 BA00000000 mov edx,0x0
-01000017 F7F1 div ecx
-01000019 89C3 mov ebx,eax
-0100001B 58 pop eax
-0100001C 01D8 add eax,ebx
-0100001E BB02000000 mov ebx,0x2
-01000023 B903000000 mov ecx,0x3
-01000028 50 push eax
-01000029 89D8 mov eax,ebx
-0100002B F7E1 mul ecx
-0100002D 89C3 mov ebx,eax
-0100002F 58 pop eax
-01000030 29D8 sub eax,ebx
-01000032 A361000001 mov [0x1000061],eax
-01000037 A161000001 mov eax,[0x1000061]
-0100003C BB03000000 mov ebx,0x3
-01000041 F7F3 div ebx
-01000043 BB03000000 mov ebx,0x3
-01000048 B904000000 mov ecx,0x4
-0100004D 50 push eax
-0100004E 89D8 mov eax,ebx
-01000050 F7E1 mul ecx
-01000052 89C3 mov ebx,eax
-01000054 58 pop eax
-01000055 01D8 add eax,ebx
-01000057 A35D000001 mov [0x100005d],eax
-0100005C F4 hlt
-0100005D 0000 add [eax],al
-0100005F 0000 add [eax],al
-01000061 0000 add [eax],al
-01000063 0000 add [eax],al
+01000000 EB3F jmp short 0x1000041
+01000002 BE00000000 mov esi,0x0
+01000007 8D3D95010001 lea edi,[dword 0x1000195]
+0100000D C60720 mov byte [edi],0x20
+01000010 47 inc edi
+01000011 46 inc esi
+01000012 83FE09 cmp esi,byte +0x9
+01000015 75F6 jnz 0x100000d
+01000017 46 inc esi
+01000018 BA00000000 mov edx,0x0
+0100001D F7F6 div esi
+0100001F 83C230 add edx,byte +0x30
+01000022 8817 mov [edi],dl
+01000024 4F dec edi
+01000025 83F800 cmp eax,byte +0x0
+01000028 75EE jnz 0x1000018
+0100002A B804000000 mov eax,0x4
+0100002F BB01000000 mov ebx,0x1
+01000034 B995010001 mov ecx,0x1000195
+01000039 BA0B000000 mov edx,0xb
+0100003E CD80 int 0x80
+01000040 C3 ret
+01000041 B80C000000 mov eax,0xc
+01000046 BB19000000 mov ebx,0x19
+0100004B B905000000 mov ecx,0x5
+01000050 50 push eax
+01000051 89D8 mov eax,ebx
+01000053 BA00000000 mov edx,0x0
+01000058 F7F1 div ecx
+0100005A 89C3 mov ebx,eax
+0100005C 58 pop eax
+0100005D 01D8 add eax,ebx
+0100005F BB02000000 mov ebx,0x2
+01000064 B903000000 mov ecx,0x3
+01000069 50 push eax
+0100006A 89D8 mov eax,ebx
+0100006C F7E1 mul ecx
+0100006E 89C3 mov ebx,eax
+01000070 58 pop eax
+01000071 29D8 sub eax,ebx
+01000073 A391010001 mov [0x1000191],eax
+01000078 A191010001 mov eax,[0x1000191]
+0100007D E880FFFFFF call 0x1000002
+01000082 A191010001 mov eax,[0x1000191]
+01000087 BB03000000 mov ebx,0x3
+0100008C BA00000000 mov edx,0x0
+01000091 F7F3 div ebx
+01000093 BB03000000 mov ebx,0x3
+01000098 B904000000 mov ecx,0x4
+0100009D 50 push eax
+0100009E 89D8 mov eax,ebx
+010000A0 F7E1 mul ecx
+010000A2 89C3 mov ebx,eax
+010000A4 58 pop eax
+010000A5 01D8 add eax,ebx
+010000A7 A38D010001 mov [0x100018d],eax
+010000AC A18D010001 mov eax,[0x100018d]
+010000B1 E84CFFFFFF call 0x1000002
+010000B6 B807000000 mov eax,0x7
+010000BB BB07000000 mov ebx,0x7
+010000C0 39D8 cmp eax,ebx
+010000C2 0F94C0 setz al
+010000C5 25FF000000 and eax,0xff
+010000CA A389010001 mov [0x1000189],eax
+010000CF A189010001 mov eax,[0x1000189]
+010000D4 E829FFFFFF call 0x1000002
+010000D9 B808000000 mov eax,0x8
+010000DE BB07000000 mov ebx,0x7
+010000E3 39D8 cmp eax,ebx
+010000E5 0F95C0 setnz al
+010000E8 25FF000000 and eax,0xff
+010000ED A389010001 mov [0x1000189],eax
+010000F2 A189010001 mov eax,[0x1000189]
+010000F7 E806FFFFFF call 0x1000002
+010000FC B808000000 mov eax,0x8
+01000101 BB09000000 mov ebx,0x9
+01000106 39D8 cmp eax,ebx
+01000108 0F9EC0 setng al
+0100010B 25FF000000 and eax,0xff
+01000110 A389010001 mov [0x1000189],eax
+01000115 A189010001 mov eax,[0x1000189]
+0100011A E8E3FEFFFF call 0x1000002
+0100011F B808000000 mov eax,0x8
+01000124 BB09000000 mov ebx,0x9
+01000129 39D8 cmp eax,ebx
+0100012B 0F9CC0 setl al
+0100012E 25FF000000 and eax,0xff
+01000133 A389010001 mov [0x1000189],eax
+01000138 A189010001 mov eax,[0x1000189]
+0100013D E8C0FEFFFF call 0x1000002
+01000142 B809000000 mov eax,0x9
+01000147 BB08000000 mov ebx,0x8
+0100014C 39D8 cmp eax,ebx
+0100014E 0F9FC0 setg al
+01000151 25FF000000 and eax,0xff
+01000156 A389010001 mov [0x1000189],eax
+0100015B A189010001 mov eax,[0x1000189]
+01000160 E89DFEFFFF call 0x1000002
+01000165 B809000000 mov eax,0x9
+0100016A BB08000000 mov ebx,0x8
+0100016F 39D8 cmp eax,ebx
+01000171 0F9DC0 setnl al
+01000174 25FF000000 and eax,0xff
+01000179 A389010001 mov [0x1000189],eax
+0100017E A189010001 mov eax,[0x1000189]
+01000183 E87AFEFFFF call 0x1000002
+01000188 F4 hlt
+01000189 0000 add [eax],al
+0100018B 0000 add [eax],al
+0100018D 0000 add [eax],al
+0100018F 0000 add [eax],al
+01000191 0000 add [eax],al
+01000193 0000 add [eax],al
+01000195 2020 and [eax],ah
+01000197 2020 and [eax],ah
+01000199 2020 and [eax],ah
+0100019B 2020 and [eax],ah
+0100019D 2020 and [eax],ah
+0100019F 0A00 or al,[eax]
diff --git a/miniany/test1.hexmust b/miniany/test1.hexmust
index 3e2a922..163e438 100644
--- a/miniany/test1.hexmust
+++ b/miniany/test1.hexmust
@@ -1,8 +1,28 @@
-00000000 b8 0c 00 00 00 bb 19 00 00 00 b9 05 00 00 00 50 |...............P|
-00000010 89 d8 ba 00 00 00 00 f7 f1 89 c3 58 01 d8 bb 02 |...........X....|
-00000020 00 00 00 b9 03 00 00 00 50 89 d8 f7 e1 89 c3 58 |........P......X|
-00000030 29 d8 a3 61 00 00 01 a1 61 00 00 01 bb 03 00 00 |)..a....a.......|
-00000040 00 f7 f3 bb 03 00 00 00 b9 04 00 00 00 50 89 d8 |.............P..|
-00000050 f7 e1 89 c3 58 01 d8 a3 5d 00 00 01 f4 00 00 00 |....X...].......|
-00000060 00 00 00 00 00 |.....|
-00000065
+00000000 eb 3f be 00 00 00 00 8d 3d 95 01 00 01 c6 07 20 |.?......=...... |
+00000010 47 46 83 fe 09 75 f6 46 ba 00 00 00 00 f7 f6 83 |GF...u.F........|
+00000020 c2 30 88 17 4f 83 f8 00 75 ee b8 04 00 00 00 bb |.0..O...u.......|
+00000030 01 00 00 00 b9 95 01 00 01 ba 0b 00 00 00 cd 80 |................|
+00000040 c3 b8 0c 00 00 00 bb 19 00 00 00 b9 05 00 00 00 |................|
+00000050 50 89 d8 ba 00 00 00 00 f7 f1 89 c3 58 01 d8 bb |P...........X...|
+00000060 02 00 00 00 b9 03 00 00 00 50 89 d8 f7 e1 89 c3 |.........P......|
+00000070 58 29 d8 a3 91 01 00 01 a1 91 01 00 01 e8 80 ff |X)..............|
+00000080 ff ff a1 91 01 00 01 bb 03 00 00 00 ba 00 00 00 |................|
+00000090 00 f7 f3 bb 03 00 00 00 b9 04 00 00 00 50 89 d8 |.............P..|
+000000a0 f7 e1 89 c3 58 01 d8 a3 8d 01 00 01 a1 8d 01 00 |....X...........|
+000000b0 01 e8 4c ff ff ff b8 07 00 00 00 bb 07 00 00 00 |..L.............|
+000000c0 39 d8 0f 94 c0 25 ff 00 00 00 a3 89 01 00 01 a1 |9....%..........|
+000000d0 89 01 00 01 e8 29 ff ff ff b8 08 00 00 00 bb 07 |.....)..........|
+000000e0 00 00 00 39 d8 0f 95 c0 25 ff 00 00 00 a3 89 01 |...9....%.......|
+000000f0 00 01 a1 89 01 00 01 e8 06 ff ff ff b8 08 00 00 |................|
+00000100 00 bb 09 00 00 00 39 d8 0f 9e c0 25 ff 00 00 00 |......9....%....|
+00000110 a3 89 01 00 01 a1 89 01 00 01 e8 e3 fe ff ff b8 |................|
+00000120 08 00 00 00 bb 09 00 00 00 39 d8 0f 9c c0 25 ff |.........9....%.|
+00000130 00 00 00 a3 89 01 00 01 a1 89 01 00 01 e8 c0 fe |................|
+00000140 ff ff b8 09 00 00 00 bb 08 00 00 00 39 d8 0f 9f |............9...|
+00000150 c0 25 ff 00 00 00 a3 89 01 00 01 a1 89 01 00 01 |.%..............|
+00000160 e8 9d fe ff ff b8 09 00 00 00 bb 08 00 00 00 39 |...............9|
+00000170 d8 0f 9d c0 25 ff 00 00 00 a3 89 01 00 01 a1 89 |....%...........|
+00000180 01 00 01 e8 7a fe ff ff f4 00 00 00 00 00 00 00 |....z...........|
+00000190 00 00 00 00 00 20 20 20 20 20 20 20 20 20 20 0a |..... .|
+000001a0 00 |.|
+000001a1