From 62924274b391dbfd16f4349bd46a2136f2a78b0e Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Wed, 13 Oct 2021 20:32:29 +0200 Subject: cc: some support for putchar and char store/load --- miniany/cc.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 9 deletions(-) (limited to 'miniany/cc.c') diff --git a/miniany/cc.c b/miniany/cc.c index e977bc9..c72d290 100644 --- a/miniany/cc.c +++ b/miniany/cc.c @@ -32,6 +32,7 @@ enum { S_WHILE, S_DO, S_PUTINT, + S_PUTCHAR, S_IDENT = 60, S_NUM = 70, S_EOI = 98, @@ -194,6 +195,8 @@ int keyword( char *ident ) case 'p': if( strcmp( ident, "putint" ) == 0 ) { return S_PUTINT; + } else if( strcmp( ident, "putchar" ) == 0 ) { + return S_PUTCHAR; } break; @@ -599,7 +602,7 @@ void putlow8reg( struct Generator *generator, int reg ) break; default: scannerPrintErrorHeader( generator->scanner ); - putstring( "error using low 8-bit subreguster of reguster '" ); + putstring( "error using low 8-bit subreguster of register '" ); putstring( generator->regName[reg] ); putstring( "'" ); putnl( ); @@ -739,27 +742,41 @@ int genLoadImm( struct Generator *generator, int intval ) return reg; } -int genLoadIdent( struct Generator *generator, char *ident ) +int genLoadIdent( struct Generator *generator, struct Symbol *sym ) { int reg; reg = genAllocReg( generator ); putstring( "mov " ); - putreg( generator, reg ); + switch( sym->type ) { + case S_INT: + putreg( generator, reg ); + break; + case S_CHAR: + putlow8reg( generator, reg ); + break; + } putstring( ", [" ); - putstring( ident ); + putstring( sym->name ); putstring( "]" ); putnl( ); return reg; } -int genStoreIdent( struct Generator *generator, int reg, char *ident ) +int genStoreIdent( struct Generator *generator, int reg, struct Symbol *sym ) { putstring( "mov [" ); - putstring( ident ); + putstring( sym->name ); putstring( "], " ); - putreg( generator, reg ); + switch( sym->type ) { + case S_INT: + putreg( generator, reg ); + break; + case S_CHAR: + putlow8reg( generator, reg ); + break; + } putnl( ); return reg; @@ -921,10 +938,10 @@ int generateFromAST( struct Generator *generator, struct ASTnode *node, int inre reg = genLoadImm( generator, node->intval ); break; case A_IDENT: - reg = genLoadIdent( generator, node->sym->name ); + reg = genLoadIdent( generator, node->sym ); break; case A_LVIDENT: - reg = genStoreIdent( generator, inreg, node->sym->name ); + reg = genStoreIdent( generator, inreg, node->sym ); break; case A_ADD: reg = genAdd( generator, leftreg, rightreg ); @@ -979,6 +996,14 @@ void genPrologue( struct Compiler *compiler ) putstring( "use32" ); putnl( ); putstring( "org $1000000" ); putnl( ); putstring( "jmp _start" ); putnl( ); + putstring( "putchar:" ); putnl( ); + putstring( "mov [putint_string_fmt], eax" ); putnl( ); + putstring( "mov eax, 4" ); putnl( ); + putstring( "mov ebx, 1" ); putnl( ); + putstring( "mov ecx, putint_string_fmt" ); putnl( ); + putstring( "mov edx, 1" ); putnl( ); + putstring( "int 0x80" ); putnl( ); + putstring( "ret" ); putnl( ); putstring( "putint:" ); putnl( ); putstring( "mov esi, 0" ); putnl( ); putstring( "lea edi, [putint_string_fmt]" ); putnl( ); @@ -1301,6 +1326,23 @@ void parsePutint( struct Compiler *compiler ) freeASTnode( node ); } +void parsePutchar( struct Compiler *compiler ) +{ + struct Parser *parser; + struct ASTnode *node; + + parser = compiler->parser; + parserExpect( parser, S_PUTCHAR, "putchar" ); + parserExpect( parser, S_LPAREN, "(" ); + node = parseExpression( parser, 0 ); + parserExpect( parser, S_RPAREN, ")" ); + parserExpect( parser, S_SEMICOLON, ";" ); + generateFromAST( compiler->generator, node, NOREG ); + putstring( "call putchar" ); putnl( ); + genFreeAllRegs( compiler->generator ); + freeASTnode( node ); +} + /* TODO c4: forward reference of function */ void parseStatementBlock( struct Compiler *compiler ); @@ -1437,6 +1479,8 @@ void parseStatement( struct Compiler *compiler ) parseAssignment( compiler ); } else if( parser->token == S_PUTINT ) { parsePutint( compiler ); + } else if( parser->token == S_PUTCHAR ) { + parsePutchar( compiler ); } else if( parser->token == S_IF ) { parseIf( compiler ); } else if( parser->token == S_WHILE ) { -- cgit v1.2.3-54-g00ecf