diff --git a/tcc.h b/tcc.h index 831c145..8e90496 100644 --- a/tcc.h +++ b/tcc.h @@ -974,7 +974,9 @@ struct TCCState { #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x) #define TOK_ASM_int TOK_INT -#define TOK_ASM_weak TOK_WEAK1 +#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x) +#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte +#define TOK_ASMDIR_LAST TOK_ASMDIR_section #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 /* only used for i386 asm opcodes definitions */ diff --git a/tccasm.c b/tccasm.c index 28e07fd..f6fe369 100644 --- a/tccasm.c +++ b/tccasm.c @@ -331,24 +331,23 @@ static void asm_parse_directive(TCCState *s1) uint8_t *ptr; /* assembler directive */ - next(); sec = cur_text_section; switch(tok) { - case TOK_ASM_align: - case TOK_ASM_p2align: - case TOK_ASM_skip: - case TOK_ASM_space: + case TOK_ASMDIR_align: + case TOK_ASMDIR_p2align: + case TOK_ASMDIR_skip: + case TOK_ASMDIR_space: tok1 = tok; next(); n = asm_int_expr(s1); - if (tok1 == TOK_ASM_p2align) + if (tok1 == TOK_ASMDIR_p2align) { if (n < 0 || n > 30) tcc_error("invalid p2align, must be between 0 and 30"); n = 1 << n; - tok1 = TOK_ASM_align; + tok1 = TOK_ASMDIR_align; } - if (tok1 == TOK_ASM_align) { + if (tok1 == TOK_ASMDIR_align) { if (n < 0 || (n & (n-1)) != 0) tcc_error("alignment must be a positive power of two"); offset = (ind + n - 1) & -n; @@ -372,7 +371,7 @@ static void asm_parse_directive(TCCState *s1) } ind += size; break; - case TOK_ASM_quad: + case TOK_ASMDIR_quad: next(); for(;;) { uint64_t vl; @@ -399,15 +398,15 @@ static void asm_parse_directive(TCCState *s1) next(); } break; - case TOK_ASM_byte: + case TOK_ASMDIR_byte: size = 1; goto asm_data; - case TOK_ASM_word: - case TOK_SHORT: + case TOK_ASMDIR_word: + case TOK_ASMDIR_short: size = 2; goto asm_data; - case TOK_LONG: - case TOK_INT: + case TOK_ASMDIR_long: + case TOK_ASMDIR_int: size = 4; asm_data: next(); @@ -433,7 +432,7 @@ static void asm_parse_directive(TCCState *s1) next(); } break; - case TOK_ASM_fill: + case TOK_ASMDIR_fill: { int repeat, size, val, i, j; uint8_t repeat_buf[8]; @@ -475,7 +474,7 @@ static void asm_parse_directive(TCCState *s1) } } break; - case TOK_ASM_org: + case TOK_ASMDIR_org: { unsigned long n; next(); @@ -488,10 +487,10 @@ static void asm_parse_directive(TCCState *s1) goto zero_pad; } break; - case TOK_ASM_globl: - case TOK_ASM_global: - case TOK_ASM_weak: - case TOK_ASM_hidden: + case TOK_ASMDIR_globl: + case TOK_ASMDIR_global: + case TOK_ASMDIR_weak: + case TOK_ASMDIR_hidden: tok1 = tok; do { Sym *sym; @@ -502,18 +501,18 @@ static void asm_parse_directive(TCCState *s1) sym = label_push(&s1->asm_labels, tok, 0); sym->type.t = VT_VOID; } - if (tok1 != TOK_ASM_hidden) + if (tok1 != TOK_ASMDIR_hidden) sym->type.t &= ~VT_STATIC; - if (tok1 == TOK_ASM_weak) + if (tok1 == TOK_ASMDIR_weak) sym->type.t |= VT_WEAK; - else if (tok1 == TOK_ASM_hidden) + else if (tok1 == TOK_ASMDIR_hidden) sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT; next(); } while (tok == ','); break; - case TOK_ASM_string: - case TOK_ASM_ascii: - case TOK_ASM_asciz: + case TOK_ASMDIR_string: + case TOK_ASMDIR_ascii: + case TOK_ASMDIR_asciz: { const uint8_t *p; int i, size, t; @@ -525,7 +524,7 @@ static void asm_parse_directive(TCCState *s1) expect("string constant"); p = tokc.str.data; size = tokc.str.size; - if (t == TOK_ASM_ascii && size > 0) + if (t == TOK_ASMDIR_ascii && size > 0) size--; for(i = 0; i < size; i++) g(p[i]); @@ -538,9 +537,9 @@ static void asm_parse_directive(TCCState *s1) } } break; - case TOK_ASM_text: - case TOK_ASM_data: - case TOK_ASM_bss: + case TOK_ASMDIR_text: + case TOK_ASMDIR_data: + case TOK_ASMDIR_bss: { char sname[64]; tok1 = tok; @@ -551,13 +550,13 @@ static void asm_parse_directive(TCCState *s1) next(); } if (n) - sprintf(sname, ".%s%d", get_tok_str(tok1, NULL), n); + sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n); else - sprintf(sname, ".%s", get_tok_str(tok1, NULL)); + sprintf(sname, "%s", get_tok_str(tok1, NULL)); use_section(s1, sname); } break; - case TOK_ASM_file: + case TOK_ASMDIR_file: { char filename[512]; @@ -575,7 +574,7 @@ static void asm_parse_directive(TCCState *s1) next(); } break; - case TOK_ASM_ident: + case TOK_ASMDIR_ident: { char ident[256]; @@ -593,7 +592,7 @@ static void asm_parse_directive(TCCState *s1) next(); } break; - case TOK_ASM_size: + case TOK_ASMDIR_size: { Sym *sym; @@ -614,7 +613,7 @@ static void asm_parse_directive(TCCState *s1) } } break; - case TOK_ASM_type: + case TOK_ASMDIR_type: { Sym *sym; const char *newtype; @@ -632,7 +631,7 @@ static void asm_parse_directive(TCCState *s1) newtype = tokc.str.data; } else { if (tok == '@' || tok == '%') - skip(tok); + next(); newtype = get_tok_str(tok, NULL); } @@ -646,7 +645,7 @@ static void asm_parse_directive(TCCState *s1) next(); } break; - case TOK_SECTION1: + case TOK_ASMDIR_section: { char sname[256]; @@ -666,12 +665,18 @@ static void asm_parse_directive(TCCState *s1) if (tok != TOK_STR) expect("string constant"); next(); + if (tok == ',') { + next(); + if (tok == '@' || tok == '%') + next(); + next(); + } } last_text_section = cur_text_section; use_section(s1, sname); } break; - case TOK_ASM_previous: + case TOK_ASMDIR_previous: { Section *sec; next(); @@ -683,13 +688,13 @@ static void asm_parse_directive(TCCState *s1) } break; #ifdef TCC_TARGET_I386 - case TOK_ASM_code16: + case TOK_ASMDIR_code16: { next(); s1->seg_size = 16; } break; - case TOK_ASM_code32: + case TOK_ASMDIR_code32: { next(); s1->seg_size = 32; @@ -698,7 +703,7 @@ static void asm_parse_directive(TCCState *s1) #endif #ifdef TCC_TARGET_X86_64 /* added for compatibility with GAS */ - case TOK_ASM_code64: + case TOK_ASMDIR_code64: next(); break; #endif @@ -763,7 +768,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess) /* horrible gas comment */ while (tok != TOK_LINEFEED) next(); - } else if (tok == '.') { + } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) { asm_parse_directive(s1); } else if (tok == TOK_PPNUM) { const char *p; diff --git a/tccpp.c b/tccpp.c index 603a65e..c8687e3 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1328,6 +1328,9 @@ ST_FUNC void parse_define(void) parse_flags |= PARSE_FLAG_SPACES; next_nomacro_spc(); if (tok == '(') { + /* must be able to parse TOK_DOTS (in asm mode '.' can be part of identifier) */ + parse_flags &= ~PARSE_FLAG_ASM_FILE; + isidnum_table['.' - CH_EOF] = 0; next_nomacro(); ps = &first; if (tok != ')') for (;;) { @@ -1355,6 +1358,9 @@ ST_FUNC void parse_define(void) } next_nomacro_spc(); t = MACRO_FUNC; + parse_flags |= (saved_parse_flags & PARSE_FLAG_ASM_FILE); + isidnum_table['.' - CH_EOF] = + (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0; } tok_str_new(&str); spc = 2; @@ -2508,7 +2514,8 @@ maybe_newline: p--; PEEKC(c, p); parse_ident_slow: - while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) { + while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) + { cstr_ccat(&tokcstr, c); PEEKC(c, p); } @@ -2567,7 +2574,7 @@ maybe_newline: cstr_reset(&tokcstr); cstr_ccat(&tokcstr, '.'); goto parse_num; - } else if ((isidnum_table['.' - CH_EOF] & IS_ID) != 0) { /* asm mode */ + } else if (parse_flags & PARSE_FLAG_ASM_FILE) { *--p = c = '.'; goto parse_ident_fast; } else if (c == '.') { @@ -3364,6 +3371,9 @@ ST_FUNC void preprocess_init(TCCState *s1) isidnum_table['$' - CH_EOF] = tcc_state->dollars_in_identifiers ? IS_ID : 0; + + isidnum_table['.' - CH_EOF] = + (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0; } ST_FUNC void preprocess_new(void) diff --git a/tcctok.h b/tcctok.h index 31b6dae..b2fbebf 100644 --- a/tcctok.h +++ b/tcctok.h @@ -301,35 +301,40 @@ #endif /* Tiny Assembler */ - DEF_ASM(byte) - DEF_ASM(word) - DEF_ASM(align) - DEF_ASM(p2align) - DEF_ASM(skip) - DEF_ASM(space) - DEF_ASM(string) - DEF_ASM(asciz) - DEF_ASM(ascii) - DEF_ASM(file) - DEF_ASM(globl) - DEF_ASM(global) - DEF_ASM(hidden) - DEF_ASM(ident) - DEF_ASM(size) - DEF_ASM(type) - DEF_ASM(text) - DEF_ASM(data) - DEF_ASM(bss) - DEF_ASM(previous) - DEF_ASM(fill) - DEF_ASM(org) - DEF_ASM(quad) + DEF_ASMDIR(byte) /* must be first directive */ + DEF_ASMDIR(word) + DEF_ASMDIR(align) + DEF_ASMDIR(p2align) + DEF_ASMDIR(skip) + DEF_ASMDIR(space) + DEF_ASMDIR(string) + DEF_ASMDIR(asciz) + DEF_ASMDIR(ascii) + DEF_ASMDIR(file) + DEF_ASMDIR(globl) + DEF_ASMDIR(global) + DEF_ASMDIR(weak) + DEF_ASMDIR(hidden) + DEF_ASMDIR(ident) + DEF_ASMDIR(size) + DEF_ASMDIR(type) + DEF_ASMDIR(text) + DEF_ASMDIR(data) + DEF_ASMDIR(bss) + DEF_ASMDIR(previous) + DEF_ASMDIR(fill) + DEF_ASMDIR(org) + DEF_ASMDIR(quad) #if defined(TCC_TARGET_I386) - DEF_ASM(code16) - DEF_ASM(code32) + DEF_ASMDIR(code16) + DEF_ASMDIR(code32) #elif defined(TCC_TARGET_X86_64) - DEF_ASM(code64) + DEF_ASMDIR(code64) #endif + DEF_ASMDIR(short) + DEF_ASMDIR(long) + DEF_ASMDIR(int) + DEF_ASMDIR(section) /* must be last directive */ #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 #include "i386-tok.h"