From c2bc809ca97bdebc8c70dd58a1c282c475a88557 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Mon, 27 Sep 2021 19:34:16 +0200 Subject: cc: added boolean expressions --- ecomp-c/emul.c | 8 ++- miniany/REQUIREMENTS | 2 + miniany/cc.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++- miniany/test1.c | 12 ++-- miniany/test1.disasmust | 155 ++++++++++++++++++++++++++++++++++++----------- miniany/test1.hexmust | 36 ++++++++--- 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 -- cgit v1.2.3-54-g00ecf