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 }