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 (4576B)
       ---
            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 }