scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

ins.c (4579B)


      1 #include <stdlib.h>
      2 
      3 #include <scc/mach.h>
      4 #include <scc/scc.h>
      5 
      6 #include "../../as.h"
      7 #include "proc.h"
      8 
      9 /*
     10  * This code is derived from PowerISA_V2.06B_V2_PUBLIC document.
     11  * All the names used in the specification are preserved in
     12  * this code.
     13  */
     14 
     15 static int
     16 getclass(Node *np)
     17 {
     18 	if (np->addr != AREG)
     19 		return 0;
     20 
     21 	switch (np->sym->value) {
     22 	case AREG_R0:
     23 	case AREG_R1:
     24 	case AREG_R2:
     25 	case AREG_R3:
     26 	case AREG_R4:
     27 	case AREG_R5:
     28 	case AREG_R6:
     29 	case AREG_R7:
     30 	case AREG_R8:
     31 	case AREG_R9:
     32 	case AREG_R10:
     33 	case AREG_R11:
     34 	case AREG_R12:
     35 	case AREG_R13:
     36 	case AREG_R14:
     37 	case AREG_R15:
     38 	case AREG_R16:
     39 	case AREG_R17:
     40 	case AREG_R18:
     41 	case AREG_R19:
     42 	case AREG_R20:
     43 	case AREG_R21:
     44 	case AREG_R22:
     45 	case AREG_R23:
     46 	case AREG_R24:
     47 	case AREG_R25:
     48 	case AREG_R26:
     49 	case AREG_R27:
     50 	case AREG_R29:
     51 	case AREG_R30:
     52 	case AREG_R31:
     53 		return GPRSCLASS;
     54 	default:
     55 		abort();
     56 	}
     57 }
     58 
     59 int
     60 match(Op *op, Node **args)
     61 {
     62 	unsigned char *p;
     63 	int arg, class, rep, opt;
     64 	Node *np;
     65 
     66 	if (!op->args)
     67 		return args == NULL;
     68 
     69 	opt = rep = 0;
     70 	for (p = op->args; arg = *p; ++p) {
     71 		if (rep)
     72 			--p;
     73 		if ((np = *args++) == NULL)
     74 			return (rep|opt) != 0;
     75 
     76 		switch (arg) {
     77 		case AOPT:
     78 			opt = 1;
     79 			break;
     80 		case AREP:
     81 			rep = 1;
     82 			break;
     83 		case AREG_GPRSCLASS:
     84 			class = GPRSCLASS;
     85 		check_class:
     86 			if ((getclass(np) & class) == 0)
     87 				return 0;
     88 			break;
     89 		case AIMM2:
     90 		case AIMM5:
     91 		case AIMM8:
     92 		case AIMM16:
     93 		case AIMM32:
     94 		case AIMM64:
     95 			if (np->addr != AIMM)
     96 				return 0;
     97 			if (toobig(np, arg))
     98 				error("overflow in immediate operand");
     99 			break;
    100 		case ASYM:
    101 			if (np->op != IDEN)
    102 				return 0;
    103 			break;
    104 		case ADIRECT:
    105 		case ASTR:
    106 			if (np->addr != arg)
    107 				return 0;
    108 			break;
    109 		default:
    110 			abort();
    111 		}
    112 	}
    113 
    114 	return *args == NULL;
    115 }
    116 
    117 Node *
    118 moperand(void)
    119 {
    120 	abort();
    121 }
    122 
    123 static void
    124 emit_packed(unsigned long ins)
    125 {
    126 	char buff[4];
    127 
    128 	if (endian == BIG_ENDIAN) {
    129 		buff[0] = ins >> 24;
    130 		buff[1] = ins >> 16;
    131 		buff[2] = ins >> 8;
    132 		buff[3] = ins;
    133 	} else {
    134 		buff[0] = ins;
    135 		buff[1] = ins >> 8;
    136 		buff[2] = ins >> 16;
    137 		buff[3] = ins >> 24;
    138 	}
    139 
    140 	emit(buff, 4);
    141 }
    142 
    143 void
    144 i_form(Op *op, Node **args)
    145 {
    146 	unsigned long ins, opcd, li, aa, lk;
    147 	long long dst;
    148 	long long max = 1l << 23;
    149 	long long min = -(1l << 23);
    150 
    151 	opcd = op->bytes[0];
    152 	aa = op->bytes[1];
    153 	lk = op->bytes[2];
    154 
    155 	dst = args[0]->sym->value;
    156 	if (dst & 0x3)
    157 		error("unaligned branch");
    158 	if (aa)
    159 		dst -= getpc() - 4;
    160 	if (dst < min || dst > max)
    161 		error("out of range branch");
    162 
    163 	li = dst;
    164 	li >>= 2;
    165 	ins = opcd<<26 | li<<2 | aa<<1 | lk;
    166 	emit_packed(ins);
    167 }
    168 
    169 void
    170 b_form(Op *op, Node **args)
    171 {
    172 	unsigned long ins, opcd, bo, bi, bd, aa, lk;
    173 	long long dst;
    174 	long long max = 1l << 13;
    175 	long long min = -(1l << 13);
    176 
    177 	opcd = op->bytes[0];
    178 	aa = op->bytes[1];
    179 	lk = op->bytes[2];
    180 
    181 	bo = args[0]->sym->value;
    182 	bi = args[1]->sym->value;
    183 
    184 	dst = args[2]->sym->value;
    185 	if (dst & 0x3)
    186 		error("unaligned branch");
    187 	if (aa)
    188 		dst -= getpc() - 4;
    189 
    190 	if (dst < min || dst > max)
    191 		error("out of range branch");
    192 	bd = dst;
    193 	bd >>= 2;
    194 
    195 	ins = opcd<<26 | bo<<21 | bi<<16 | bd<<11 | aa<<1 | lk;
    196 	emit_packed(ins);
    197 }
    198 
    199 void
    200 sc_form(Op *op, Node **args)
    201 {
    202 	abort();
    203 }
    204 
    205 void
    206 d_form(Op *op, Node **args)
    207 {
    208 	abort();
    209 }
    210 
    211 void
    212 ds_form(Op *op, Node **args)
    213 {
    214 	abort();
    215 }
    216 
    217 void
    218 dq_form(Op *op, Node **args)
    219 {
    220 	abort();
    221 }
    222 
    223 void
    224 x_form(Op *op, Node **args)
    225 {
    226 	abort();
    227 }
    228 
    229 void
    230 xl_form(Op *op, Node **args)
    231 {
    232 	unsigned long ins, bo, bi, bh, lk;
    233 	unsigned long opcd1, opcd2;
    234 	long long dst;
    235 
    236 	opcd1 = op->bytes[0];
    237 	opcd2 = op->bytes[1]<<8 | op->bytes[2];
    238 	lk = op->bytes[3];
    239 
    240 	bo = args[0]->sym->value;
    241 	bi = args[1]->sym->value;
    242 	bh = args[2]->sym->value;
    243 
    244 	ins = opcd1<<26 | bo<<21 | bi<<16 | bh<<11 | opcd2<<1 | lk;
    245 	emit_packed(ins);
    246 }
    247 
    248 void
    249 xfx_form(Op *op, Node **args)
    250 {
    251 	abort();
    252 }
    253 
    254 void
    255 xlfdorm_form(Op *op, Node **args)
    256 {
    257 	abort();
    258 }
    259 
    260 void
    261 xx1_form(Op *op, Node **args)
    262 {
    263 	abort();
    264 }
    265 
    266 void
    267 xx2_form(Op *op, Node **args)
    268 {
    269 	abort();
    270 }
    271 
    272 void
    273 xx3_form(Op *op, Node **args)
    274 {
    275 	abort();
    276 }
    277 
    278 void
    279 xx4_form(Op *op, Node **args)
    280 {
    281 	abort();
    282 }
    283 
    284 void
    285 xs_form(Op *op, Node **args)
    286 {
    287 	abort();
    288 }
    289 
    290 void
    291 xo_form(Op *op, Node **args)
    292 {
    293 	abort();
    294 }
    295 
    296 void
    297 a_form(Op *op, Node **args)
    298 {
    299 	abort();
    300 }
    301 
    302 void
    303 m_form(Op *op, Node **args)
    304 {
    305 	abort();
    306 }
    307 
    308 void
    309 md_form(Op *op, Node **args)
    310 {
    311 	abort();
    312 }
    313 
    314 void
    315 mds_form(Op *op, Node **args)
    316 {
    317 	abort();
    318 }
    319 
    320 void
    321 va_form(Op *op, Node **args)
    322 {
    323 	abort();
    324 }
    325 
    326 void
    327 vc_form(Op *op, Node **args)
    328 {
    329 	abort();
    330 }
    331 
    332 void
    333 vx_form(Op *op, Node **args)
    334 {
    335 	abort();
    336 }
    337 
    338 void
    339 evs_form(Op *op, Node **args)
    340 {
    341 	abort();
    342 }
    343 
    344 void
    345 z22_form(Op *op, Node **args)
    346 {
    347 	abort();
    348 }
    349 
    350 void
    351 z23_form(Op *op, Node **args)
    352 {
    353 	abort();
    354 }