ins.c - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
       ins.c (3344B)
       ---
            1 #include <string.h>
            2 
            3 #include <scc/mach.h>
            4 #include <scc/scc.h>
            5 
            6 #include "as.h"
            7 
            8 extern Section *sabs, *sbss, *sdata, *stext;
            9 
           10 enum {
           11         EQU,
           12         COMMON,
           13         SIZE,
           14         XSTRING,
           15         ASCII,
           16         TYPE,
           17 };
           18 
           19 static void
           20 reloc(Symbol *sym,
           21        unsigned flags,
           22        unsigned size,
           23        unsigned nbits,
           24        unsigned shift)
           25 {
           26 }
           27 
           28 char *
           29 tobytes(TUINT v, int nbytes, int inc)
           30 {
           31         static char buf[sizeof(TUINT)];
           32         int idx;
           33 
           34         idx = (inc < 0) ? nbytes-1 : 0;
           35         while (nbytes--) {
           36                 buf[idx] = v;
           37                 idx += inc;
           38                 v >>= 8;
           39         }
           40 
           41         if (v)
           42                 error("overflow in immediate value");
           43         return buf;
           44 }
           45 
           46 void
           47 noargs(Op *op, Node **args)
           48 {
           49         emit(op->bytes, op->size);
           50 }
           51 
           52 static void
           53 xstring(int which, Node **args)
           54 {
           55         Node *np;
           56         char *s;
           57         size_t len;
           58 
           59         while (np = *args++) {
           60                 s = np->sym->name;
           61                 len = strlen(s);
           62                 len += which == XSTRING;
           63                 emit(s, len);
           64         }
           65 }
           66 
           67 void
           68 string(Op *op, Node **args)
           69 {
           70         xstring(STRING, args);
           71 }
           72 
           73 void
           74 ascii(Op *op, Node **args)
           75 {
           76         xstring(STRING, args);
           77 }
           78 
           79 void
           80 def(Node **args, int siz)
           81 {
           82         Node *np;
           83 
           84         while (np = *args++) {
           85                 Symbol *sym = np->sym;
           86 
           87                 if ((sym->flags & FABS) == 0)
           88                         reloc(sym, 0, siz, siz * 8, 0);
           89                 emit(tobytes(sym->value, siz, endian), siz);
           90         }
           91 }
           92 
           93 void
           94 defb(Op *op, Node **args)
           95 {
           96         def(args, 1);
           97 }
           98 
           99 void
          100 defw(Op *op, Node **args)
          101 {
          102         def(args, 2);
          103 }
          104 
          105 void
          106 defd(Op *op, Node **args)
          107 {
          108         def(args, 4);
          109 }
          110 
          111 void
          112 defq(Op *op, Node **args)
          113 {
          114         def(args, 8);
          115 }
          116 
          117 static void
          118 symexp(int which, Op *op, Node **args)
          119 {
          120         Symbol *sym, *exp;
          121         static char *cmds[] = {
          122                 [EQU] = "equ",
          123                 [COMMON] = "common",
          124                 [SIZE] = "size",
          125         };
          126         char *cmd = cmds[which];
          127 
          128         if (args[1]) {
          129                 sym = args[0]->sym;
          130                 exp = args[1]->sym;
          131         } else if (linesym) {
          132                 sym = linesym;
          133                 exp = args[0]->sym;
          134         } else {
          135                 error("%s pseudo instruction lacks a label", cmd);
          136         }
          137 
          138         if ((exp->flags & FABS) == 0)
          139                 error("%s expression is not an absolute expression", cmd);
          140 
          141         switch (which) {
          142         case EQU:
          143                 if (pass == 1 && (sym->flags & FDEF))
          144                         error("redefinition of symbol '%s'", sym->name);
          145                 sym->value = exp->value;
          146                 sym->flags |= FDEF;
          147                 break;
          148         case COMMON:
          149                 sym->flags |= FCOMMON;
          150         case SIZE:
          151                 sym->size = exp->value;
          152                 break;
          153         case TYPE:
          154                 sym->dtype = exp->value;
          155                 break;
          156         }
          157 }
          158 
          159 void
          160 equ(Op *op, Node **args)
          161 {
          162         symexp(EQU, op, args);
          163 }
          164 
          165 void
          166 common(Op *op, Node **args)
          167 {
          168         symexp(COMMON, op, args);
          169 }
          170 
          171 void
          172 size(Op *op, Node **args)
          173 {
          174         symexp(SIZE, op, args);
          175 }
          176 
          177 void
          178 type(Op *op, Node **args)
          179 {
          180         symexp(TYPE, op, args);
          181 }
          182 
          183 void
          184 section(Op *op, Node **args)
          185 {
          186         Symbol *sym = args[0]->sym;
          187         char *attr = NULL;
          188 
          189         if (args[1])
          190                 attr = args[1]->sym->name;
          191 
          192         defsec(sym->name, attr);
          193 }
          194 
          195 void
          196 text(Op *op, Node **args)
          197 {
          198         cursec = stext;
          199 }
          200 
          201 void
          202 data(Op *op, Node **args)
          203 {
          204         cursec = sdata;
          205 }
          206 
          207 void
          208 bss(Op *op, Node **args)
          209 {
          210         cursec = sbss;
          211 }
          212 
          213 void
          214 extrn(Op *op, Node **args)
          215 {
          216         Symbol *sym = args[0]->sym;
          217 
          218         sym->flags |= FEXTERN;
          219 }
          220 
          221 void
          222 global(Op *op, Node **args)
          223 {
          224         Symbol *sym = args[0]->sym;
          225 
          226         sym->flags |= FGLOBAL;
          227 }
          228 
          229 void
          230 align(Op *op, Node **args)
          231 {
          232         Symbol *sym = args[0]->sym;
          233         TUINT pcal, pc, al;
          234 
          235         if ((sym->flags & FABS) == 0)
          236                 error("align expression is not an absolute expression");
          237         if ((al = sym->value) == 0)
          238                 return;
          239 
          240         al--;
          241         pc = getpc();
          242         pcal = pc+al & ~al;
          243 
          244         for (al = pcal - pc; al > 0; --al)
          245                 emit((char []) {0}, 1);
          246 }
          247 
          248 void
          249 end(Op *op, Node **args)
          250 {
          251         endpass = 1;
          252 }
          253 
          254 void
          255 include(Op *op, Node **args)
          256 {
          257         addinput(args[0]->sym->name);
          258 }