summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-07-23 17:28:43 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-07-23 17:28:43 +0200
commit33a4671260b567173c2c931992cd096513f4b9ca (patch)
tree219e856ebcce96d0238affc835cbd915c6d2820e
parentc3c7f10a4f6b55abbc5e577930ed59d94577cb59 (diff)
downloadcompilertests-33a4671260b567173c2c931992cd096513f4b9ca.tar.gz
compilertests-33a4671260b567173c2c931992cd096513f4b9ca.tar.bz2
parsing $ and $$ in asm-i386
- freestanding libc: added ungetc function with one pushback character - asm-i386: for now adding $ and $$ as special addresses to the operands in the expression tree
-rw-r--r--ecomp-c/asm-i386.c49
-rw-r--r--ecomp-c/libc-freestanding.c16
-rw-r--r--ecomp-c/tests/asm-i386/elf.asm3
3 files changed, 58 insertions, 10 deletions
diff --git a/ecomp-c/asm-i386.c b/ecomp-c/asm-i386.c
index 3cb6ff1..a0a65a7 100644
--- a/ecomp-c/asm-i386.c
+++ b/ecomp-c/asm-i386.c
@@ -70,8 +70,8 @@ enum {
};
static int DEBUG_GETCHAR = 0;
-static int DEBUG_SCANNER = 1;
-static int DEBUG_PARSER = 1;
+static int DEBUG_SCANNER = 0;
+static int DEBUG_PARSER = 0;
/* scanner */
@@ -92,6 +92,8 @@ typedef enum {
S_minus,
S_star,
S_slash,
+ S_current_org,
+ S_current_addr,
S_eof
} S_Symbol;
@@ -112,6 +114,8 @@ static char *symname[S_eof+1] = {
"-",
"*",
"/",
+ "$$",
+ "$",
"eof"
};
@@ -203,6 +207,11 @@ static int getChar( void )
return c;
}
+static void ungetChar( int c )
+{
+ ungetc( c, stdin );
+}
+
static int isWhite( int c )
{
if( c == ' ' || c == '\r' || c == '\t' ) return 1;
@@ -373,8 +382,18 @@ static S_Symbol getSym( void )
s = S_newline;
break;
case '$':
- hexnumber( );
- s = S_number;
+ look = getChar( );
+ if( look == '$' ) {
+ s = S_current_org;
+ } else if( ( look >= '0' && look <= '9' ) ||
+ ( look >= 'a' && look <= 'f' ) ||
+ ( look >= 'A' && look <= 'F' ) ) {
+ ungetChar( look );
+ s = S_number;
+ hexnumber( );
+ } else {
+ s = S_current_addr;
+ }
break;
case '\"':
string( );
@@ -612,7 +631,9 @@ typedef struct Symbol {
struct Symbol *symbol = NULL;
enum {
- ADDRESS_UNDEFINED = 0x7FFFFFFF
+ ADDRESS_UNDEFINED = 0x7FFFFFFF,
+ ADDRESS_CURRENT_ORG = 0x7FFFFFFE,
+ ADDRESS_CURRENT_ADDR = 0x7FFFFFFD
};
static Symbol *get_symbol( char *name )
@@ -1060,7 +1081,17 @@ static ExpressionNode *parseFactor( void )
node = create_expression_node( );
node->type = EXPRESSION_NODE_TYPE_VAR;
node->symbol = symbol;
- sym = getSym( );
+ sym = getSym( );
+ } else if( sym == S_current_org ) {
+ node = create_expression_node( );
+ node->type = EXPRESSION_NODE_TYPE_CONST;
+ node->integer_value = ADDRESS_CURRENT_ORG;
+ sym = getSym( );
+ } else if( sym == S_current_addr ) {
+ node = create_expression_node( );
+ node->type = EXPRESSION_NODE_TYPE_CONST;
+ node->integer_value = ADDRESS_CURRENT_ADDR;
+ sym = getSym( );
} else {
Abort( "Expected a literal, a variable or a constant." );
}
@@ -1105,7 +1136,7 @@ static ExpressionNode *parseExpression( void )
return node;
}
-static int evaluate_const_expression_as_integer( ExpressionNode *node )
+static int evaluateExpression( ExpressionNode *node )
{
switch( node->type ) {
case EXPRESSION_NODE_TYPE_CONST:
@@ -1138,13 +1169,13 @@ static OperandInfo *parseOperand( OpcodeInfo *opcode_info )
assign_label( operand_info, ident );
}
sym = getSym( );
- } else if( sym == S_number ) {
+ } else if( sym == S_number || sym == S_current_org || sym == S_current_addr ) {
/* absolute operand, like in mov eax, $1,
* we have assemble-time expressions here
*/
operand_info->type = OPERAND_ABSOLUTE;
operand_info->node = parseExpression( );
- operand_info->num = evaluate_const_expression_as_integer( operand_info->node );
+ operand_info->num = evaluateExpression( operand_info->node );
free_expression_node( operand_info->node );
} else if( sym == S_string ) {
operand_info->type = OPERAND_ABSOLUTE;
diff --git a/ecomp-c/libc-freestanding.c b/ecomp-c/libc-freestanding.c
index ca41ae7..f37aa83 100644
--- a/ecomp-c/libc-freestanding.c
+++ b/ecomp-c/libc-freestanding.c
@@ -399,9 +399,10 @@ typedef struct {
int readpos;
int size;
char buf[INTERNAL_STDIO_BUFSIZE];
+ int pushback;
} FILE;
-static FILE fds[3] = { { STDIN_FILENO, 0, 0, "" }, { STDOUT_FILENO, 0, 0, "" }, { STDERR_FILENO, 0, 0, "" } };
+static FILE fds[3] = { { STDIN_FILENO, 0, 0, "", 0 }, { STDOUT_FILENO, 0, 0, "", 0 }, { STDERR_FILENO, 0, 0, "", 0 } };
FILE *stdin = &fds[0];
FILE *stdout = &fds[1];
@@ -586,6 +587,12 @@ int fgetc( FILE *stream )
{
int c;
+ if( stream->pushback != 0 ) {
+ c = stream->pushback;
+ stream->pushback = 0;
+ return c;
+ }
+
if( stream->size == 0 ) {
int n = read_string( stream->fileno, stream->buf, INTERNAL_STDIO_BUFSIZE );
if( n < 0 ) {
@@ -606,6 +613,13 @@ int fgetc( FILE *stream )
return c;
}
+int ungetc( int c, FILE *stream )
+{
+ stream->pushback = c;
+
+ return c;
+}
+
int getchar( void )
{
return fgetc( stdin );
diff --git a/ecomp-c/tests/asm-i386/elf.asm b/ecomp-c/tests/asm-i386/elf.asm
index e23f61d..3fba61e 100644
--- a/ecomp-c/tests/asm-i386/elf.asm
+++ b/ecomp-c/tests/asm-i386/elf.asm
@@ -2,6 +2,9 @@ format binary
use32
org $08048000
ehdr:
+mov eax, $$
+mov ebx, $
+mov ecx, $1
db $7F, "ELF" ; e_ident: magic
db 1 ; EI_CLASS: ELFCLASS32
db 1 ; EI_BYTE: ELFDATA2LSB (little endian, 2's complement)