/* * INSN.C * * (c)Copyright 2016, Matthew Dillon, All Rights Reserved. See the * COPYRIGHT file at the base of the distribution. */ #include "defs.h" void PsopSECTION(RASParser *p, rinsn_t *rin __unused) { } void PsopENDSECTION(RASParser *p, rinsn_t *rin __unused) { } /* * Import a global */ void PsopEXTERN(RASParser *p, rinsn_t *rin __unused) { } /* * .BSS - (uninitialized rw data - zerod on start) */ void PsopBSS(RASParser *p, rinsn_t *rin __unused) { printf("\t.bss\n"); } /* * .DATA - initialized rw data */ void PsopDATA(RASParser *p, rinsn_t *rin __unused) { printf("\t.data\n"); } /* * .RODATA - initialized ro data */ void PsopRODATA(RASParser *p, rinsn_t *rin __unused) { printf("\t.section\t.rodata\n"); } /* * .TEXT - ro code */ void PsopTEXT(RASParser *p, rinsn_t *rin __unused) { printf("\t.text\n"); } /* * .ALIGN - align data or code (code aligned with NOPs) */ void PsopALIGN(RASParser *p, rinsn_t *rin __unused) { runesize_t align; rastoken_t t; t = RasToken(p); t = RasParseSizeValue(p, t, &align); printf("\t.align\t%jd\n", (intmax_t)align); } /* * .WEAK - Create a weak symbol equivalance */ void PsopWEAK(RASParser *p, rinsn_t *rin __unused) { rastoken_t t; rsym_t *ssym; rsym_t *dsym; t = RasToken(p); t = RasParseSymbol(p, t, &dsym); if (t != TOK_COMMA) { RasError(p, "Syntax error"); return; } t = RasToken(p); /* skip .weak */ t = RasParseSymbol(p, t, &ssym); printf("\t.weak\t%s\n", dsym->id + 1); printf("\t.equ\t%s, %s\n", dsym->id + 1, ssym->id + 1); } /* * Export as global */ void PsopGLOBL(RASParser *p, rinsn_t *rin __unused) { } /* * CTORS section */ void PsopCTORS(RASParser *p, rinsn_t *rin __unused) { printf("\t.section\trunectors, \"aGw\", @progbits, comdat\n"); } /* * FILE fileno "filename" */ void PsopFILE(RASParser *p, rinsn_t *rin __unused) { runesize_t loc_file; rastoken_t t; t = RasToken(p); t = RasParseSizeValue(p, t, &loc_file); if (t != TOK_STRING) { RasError(p, "Expected filename"); return; } printf("\t.file\t%jd %*.*s\n", (intmax_t)loc_file, (int)(p->tend - p->tbase), (int)(p->tend - p->tbase), p->tbase); } /* * LOC fileno lineno arg3 */ void PsopLOC(RASParser *p, rinsn_t *rin) { runesize_t loc_file; runesize_t loc_line; runesize_t loc_arg3; rastoken_t t; t = RasToken(p); t = RasParseSizeValue(p, t, &loc_file); t = RasParseSizeValue(p, t, &loc_line); t = RasParseSizeValue(p, t, &loc_arg3); if (rin) { rin->loc_file = loc_file; rin->loc_line = loc_line; } else { printf("\t.loc\t%jd %jd %jd\n", (intmax_t)loc_file, (intmax_t)loc_line, (intmax_t)loc_arg3); } } /* * .ZERO - Layout an area with zerod bytes. */ void PsopZERO(RASParser *p, rinsn_t *rin __unused) { runesize_t bytes; runesize_t align = 0; rastoken_t t; t = RasToken(p); t = RasParseSizeValue(p, t, &bytes); if (t == TOK_COMMA) { t = RasToken(p); t = RasParseSizeValue(p, t, &align); } if (align && align != 1) printf("\t.align\t%jd\n", (intmax_t)align); printf("\t.zero\t%jd\n", (intmax_t)bytes); } /* * .* - Layout an area with initialized data * * .int{8,16,32,64,128} * .uint{8,16,32,64,128} * .float * .double * .ldouble * * XXX require natural alignment, do not generate pad. */ static int tohex(char c); void PsopLAYOUT(RASParser *p, rinsn_t *rin __unused) { rastoken_t t; int isunsigned __unused = 0; int isfloating = 0; int size; rsym_t *sym; const char *id; id = p->sym->id; if (strcmp(id, "int8") == 0) { id = ".byte"; size = 1; } else if (strcmp(id, "int16") == 0) { id = ".value"; size = 2; } else if (strcmp(id, "int32") == 0) { id = ".long"; size = 4; } else if (strcmp(id, "int64") == 0) { id = ".quad"; size = 8; } else if (strcmp(id, "int128") == 0) { id = ".long"; /* not used */ size = 16; } else if (strcmp(id, "uint8") == 0) { id = ".byte"; size = 1; isunsigned = 1; } else if (strcmp(id, "uint16") == 0) { id = ".value"; size = 2; isunsigned = 1; } else if (strcmp(id, "uint32") == 0) { id = ".long"; size = 4; isunsigned = 1; } else if (strcmp(id, "uint64") == 0) { printf("\t.quad\t"); size = 8; isunsigned = 1; } else if (strcmp(id, "uint128") == 0) { id = ".long"; /* not used */ size = 16; isunsigned = 1; } else if (strcmp(id, "float") == 0) { id = ".long"; /* not used */ size = 4; isfloating = 1; } else if (strcmp(id, "double") == 0) { id = ".quad"; /* not used */ size = 8; isfloating = 1; } else if (strcmp(id, "ldouble") == 0) { id = ".long"; /* not used */ size = 16; isfloating = 1; } else { RasError(p, "Unknown layout token"); return; } t = RasToken(p); while (t) { if (t == TOK_ID) { RasError(p, "Unexpected identifier"); t = RasToken(p); } else if (t == TOK_SYMBOL) { sym = p->sym; printf("\t%s\t%s", id, sym->id + 1); dassert(isfloating == 0); dassert(size != 16); t = RasToken(p); if (t == TOK_VALUE && (p->flags & RASPF_DIDPLMI)) { if ((int64_t)p->valuelo < 0) printf("%jd", (intmax_t)(int64_t)p->valuelo); else printf("+%jd", (intmax_t)(int64_t)p->valuelo); t = RasToken(p); } printf("\n"); } else if (t == TOK_VALUE) { if (isfloating) { switch(size) { case 4: printf("\t.long\t%d\n", (int32_t)p->valuelo); break; case 8: printf("\t.long\t%d\n", (int32_t)p->valuelo); printf("\t.long\t%d\n", (int32_t)(p->valuelo >> 32)); break; case 16: printf("\t.long\t%d\n", (int32_t)p->valuelo); printf("\t.long\t%d\n", (int32_t)(p->valuelo >> 32)); printf("\t.long\t%d\n", (int32_t)p->valuehi); printf("\t.long\t%d\n", (int32_t)(p->valuehi >> 32)); break; default: dpanic("Unsupported floating size %zd", size); } } else if (size == 16) { printf("\t.long\t%d\n", (int32_t)p->valuelo); printf("\t.long\t%d\n", (int32_t)(p->valuelo >> 32)); printf("\t.long\t%d\n", (int32_t)p->valuehi); printf("\t.long\t%d\n", (int32_t)(p->valuehi >> 32)); } else { printf("\t%s\t%jd\n", id, (intmax_t)p->valuelo); } t = RasToken(p); } else if (t == TOK_STRING) { size_t i; size_t bytes; dassert(isfloating == 0); dassert(size != 16); bytes = p->tend - p->tbase; printf("\t# string %*.*s\n", (int)bytes, (int)bytes, p->tbase); for (i = 1; i < bytes - 1; ++i) { if (p->tbase[i] == '\\') { printf("\t%s\t%d\n", id, (tohex(p->tbase[i+1]) << 4) | tohex(p->tbase[i+2])); i += 2; } else { printf("\t%s\t%d\n", id, (uint8_t)p->tbase[i]); } } t = RasToken(p); } else { RasError(p, "Expected symbol or value"); t = RasToken(p); } if (t == 0) break; if (t != TOK_COMMA) { RasError(p, "Expected comma"); break; } t = RasToken(p); } } static int tohex(char c) { if (c >= '0' && c <= '9') return(c - '0'); if (c >= 'a' && c <= 'f') return(c - 'a' + 10); if (c >= 'A' && c <= 'F') return(c - 'A' + 10); return 0; }