diff options
| author | seyko <seyko2@gmail.com> | 2016-04-22 18:29:56 +0300 |
|---|---|---|
| committer | seyko <seyko2@gmail.com> | 2016-04-22 18:29:56 +0300 |
| commit | 1f49441a27da312f75feb53db14c4e025f7eb7a2 (patch) | |
| tree | ec78bd152ecf7e7b5e11b338e7020d50e89f7fb6 | |
| parent | edcb15c31fd9182d8aa2185d8da6d5faf081863d (diff) | |
| download | tinycc-1f49441a27da312f75feb53db14c4e025f7eb7a2.tar.gz tinycc-1f49441a27da312f75feb53db14c4e025f7eb7a2.tar.bz2 | |
.rept asm directive
and '.' alone is a token now in *.S (not an identifier)
representing a current position in the code (PC).
| -rw-r--r-- | tccasm.c | 37 | ||||
| -rw-r--r-- | tccpp.c | 3 | ||||
| -rw-r--r-- | tcctok.h | 2 |
3 files changed, 41 insertions, 1 deletions
@@ -32,6 +32,8 @@ ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n) } ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); +static int tcc_assemble_internal(TCCState *s1, int do_preprocess); +static Sym sym_dot; /* We do not use the C expression parser to handle symbols. Maybe the C expression parser could be tweaked to do so. */ @@ -101,6 +103,14 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) asm_expr(s1, pe); skip(')'); break; + case '.': + pe->v = 0; + pe->sym = &sym_dot; + sym_dot.type.t = VT_VOID | VT_STATIC; + sym_dot.r = cur_text_section->sh_num; + sym_dot.jnext = ind; + next(); + break; default: if (tok >= TOK_IDENT) { /* label case : if the label was not found, add one */ @@ -474,6 +484,33 @@ static void asm_parse_directive(TCCState *s1) } } break; + case TOK_ASMDIR_rept: + { + int repeat; + TokenString init_str; + ParseState saved_parse_state = {0}; + next(); + repeat = asm_int_expr(s1); + tok_str_new(&init_str); + next(); + while ((tok != TOK_ASMDIR_endr) && (tok != CH_EOF)) { + tok_str_add_tok(&init_str); + next(); + } + if (tok == CH_EOF) tcc_error("we at end of file, .endr not found"); + next(); + tok_str_add(&init_str, -1); + tok_str_add(&init_str, 0); + save_parse_state(&saved_parse_state); + begin_macro(&init_str, 0); + while (repeat-- > 0) { + tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS)); + macro_ptr = init_str.str; + } + end_macro(); + restore_parse_state(&saved_parse_state); + break; + } case TOK_ASMDIR_org: { unsigned long n; @@ -2784,7 +2784,8 @@ maybe_newline: cstr_reset(&tokcstr); cstr_ccat(&tokcstr, '.'); goto parse_num; - } else if (parse_flags & PARSE_FLAG_ASM_FILE) { + } else if ((parse_flags & PARSE_FLAG_ASM_FILE) + && (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) { *--p = c = '.'; goto parse_ident_fast; } else if (c == '.') { @@ -324,6 +324,8 @@ DEF_ASMDIR(bss) DEF_ASMDIR(previous) DEF_ASMDIR(fill) + DEF_ASMDIR(rept) + DEF_ASMDIR(endr) DEF_ASMDIR(org) DEF_ASMDIR(quad) #if defined(TCC_TARGET_I386) |
