aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tccasm.c37
-rw-r--r--tccpp.c3
-rw-r--r--tcctok.h2
3 files changed, 41 insertions, 1 deletions
diff --git a/tccasm.c b/tccasm.c
index f6fe369..72121e4 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -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;
diff --git a/tccpp.c b/tccpp.c
index b991944..e1fabbb 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -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 == '.') {
diff --git a/tcctok.h b/tcctok.h
index 2cb310b..a75edc8 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -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)