Home
       ins.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       ins.c (5731B)
       ---
            1 #include <stdlib.h>
            2 #include <string.h>
            3 
            4 #include <scc/mach.h>
            5 #include <scc/scc.h>
            6 
            7 #include "../../as.h"
            8 #include "proc.h"
            9 
           10 #define addrbyte(mod, reg, rm) ((mod) << 6 | (reg) << 3 | (rm))
           11 
           12 /*
           13  * This implementation is based in:
           14  *        - x86 Opcode Structure and Instruction Overview - Fraunhofer-Institut
           15  *        fÜr kommunikation, informationsverarbeitung und ergonomie fkie.
           16  *        - Intel® 64 and IA-32 Architectures Software Developer’s Manual.
           17  *        - Encoding Real x86 Instructions - CIS-77 lectures.
           18  */
           19 enum addr_mode {
           20         MEM_MODE   = 0,
           21         MEM8_MODE  = 1,
           22         MEM16_MODE = 2,
           23         REG_MODE   = 3,
           24 };
           25 
           26 static int
           27 getclass(Node *np)
           28 {
           29         if (np->addr != AREG)
           30                 return 0;
           31 
           32         switch (np->sym->value) {
           33         case AREG_AL:
           34         case AREG_AH:
           35         case AREG_BL:
           36         case AREG_BH:
           37         case AREG_CL:
           38         case AREG_CH:
           39         case AREG_DL:
           40         case AREG_DH:
           41                 return R8CLASS;
           42 
           43         case AREG_AX:
           44         case AREG_BX:
           45         case AREG_CX:
           46         case AREG_DX:
           47         case AREG_DI:
           48         case AREG_SI:
           49         case AREG_SP:
           50         case AREG_BP:
           51                 return R16CLASS;
           52 
           53         case AREG_CS:
           54         case AREG_DS:
           55         case AREG_SS:
           56         case AREG_ES:
           57         case AREG_FS:
           58         case AREG_GS:
           59 
           60         case AREG_EFLAGS:
           61         case AREG_CF:
           62         case AREG_PF:
           63         case AREG_AF:
           64         case AREG_ZF:
           65         case AREG_SF:
           66         case AREG_TF:
           67         case AREG_IF:
           68         case AREG_DF:
           69         case AREG_OF:
           70         case AREG_IOPL:
           71         case AREG_NT:
           72         case AREG_RF:
           73         case AREG_VM:
           74         case AREG_AC:
           75         case AREG_VIF:
           76         case AREG_VIP:
           77         case AREG_ID:
           78 
           79         case AREG_EAX:
           80         case AREG_RAX:
           81 
           82         case AREG_EBX:
           83         case AREG_RBX:
           84 
           85         case AREG_ECX:
           86         case AREG_RCX:
           87 
           88         case AREG_EDX:
           89         case AREG_RDX:
           90 
           91         case AREG_SIL:
           92         case AREG_ESI:
           93         case AREG_RSI:
           94         case AREG_DIL:
           95         case AREG_EDI:
           96         case AREG_RDI:
           97 
           98         case AREG_SPL:
           99         case AREG_ESP:
          100         case AREG_RSP:
          101 
          102         case AREG_BPL:
          103         case AREG_EBP:
          104         case AREG_RBP:
          105 
          106         case AREG_R0:
          107         case AREG_MM0:
          108         case AREG_R1:
          109         case AREG_MM1:
          110         case AREG_R2:
          111         case AREG_MM2:
          112         case AREG_R3:
          113         case AREG_MM3:
          114         case AREG_R4:
          115         case AREG_MM4:
          116         case AREG_R5:
          117         case AREG_MM5:
          118         case AREG_R6:
          119         case AREG_MM6:
          120         case AREG_R7:
          121         case AREG_MM7:
          122 
          123         case AREG_R8:
          124         case AREG_R8L:
          125         case AREG_R8W:
          126         case AREG_R9:
          127         case AREG_R9L:
          128         case AREG_R9W:
          129         case AREG_R10:
          130         case AREG_R10L:
          131         case AREG_R10W:
          132         case AREG_R11:
          133         case AREG_R11L:
          134         case AREG_R11W:
          135         case AREG_R12:
          136         case AREG_R12L:
          137         case AREG_R12W:
          138         case AREG_R13:
          139         case AREG_R13L:
          140         case AREG_R13W:
          141         case AREG_R14:
          142         case AREG_R14L:
          143         case AREG_R14W:
          144         case AREG_R15:
          145         case AREG_R15L:
          146         case AREG_R15W:
          147 
          148         case AREG_XMM0:
          149         case AREG_XMM1:
          150         case AREG_XMM2:
          151         case AREG_XMM3:
          152         case AREG_XMM4:
          153         case AREG_XMM5:
          154         case AREG_XMM6:
          155         case AREG_XMM7:
          156         case AREG_XMM8:
          157         case AREG_XMM9:
          158         case AREG_XMM10:
          159         case AREG_XMM11:
          160         case AREG_XMM12:
          161         case AREG_XMM13:
          162         case AREG_XMM14:
          163         case AREG_XMM15:
          164 
          165         case AREG_YMM0:
          166         case AREG_YMM1:
          167         case AREG_YMM2:
          168         case AREG_YMM3:
          169         case AREG_YMM4:
          170         case AREG_YMM5:
          171         case AREG_YMM6:
          172         case AREG_YMM7:
          173         case AREG_YMM8:
          174         case AREG_YMM9:
          175         case AREG_YMM10:
          176         case AREG_YMM11:
          177         case AREG_YMM12:
          178         case AREG_YMM13:
          179         case AREG_YMM14:
          180         case AREG_YMM15:
          181 
          182         case AREG_MXCSR:
          183                 return 0;
          184         default:
          185                 abort();
          186         }
          187 }
          188 
          189 int
          190 match(Op *op, Node **args)
          191 {
          192         unsigned char *p;
          193         int arg, class, rep, opt;
          194         Node *np;
          195 
          196         if (!op->args)
          197                 return args == NULL;
          198 
          199         opt = rep = 0;
          200         for (p = op->args; arg = *p; ++p) {
          201                 if (rep)
          202                         --p;
          203                 if ((np = *args++) == NULL)
          204                         return (rep|opt) != 0;
          205 
          206                 switch (arg) {
          207                 case AOPT:
          208                         opt = 1;
          209                         break;
          210                 case AREP:
          211                         rep = 1;
          212                         break;
          213                 case AREG_R8CLASS:
          214                         class = R8CLASS;
          215                         goto check_class;
          216                 case AREG_R16CLASS:
          217                         class = R16CLASS;
          218                 check_class:
          219                         if ((getclass(np) & class) == 0)
          220                                 return 0;
          221                         break;
          222                 case AIMM8:
          223                 case AIMM16:
          224                 case AIMM32:
          225                 case AIMM64:
          226                         if (np->addr != AIMM)
          227                                 return 0;
          228                         if (toobig(np, arg))
          229                                 error("overflow in immediate operand");
          230                         break;
          231                 case ASYM:
          232                         if (np->op != IDEN)
          233                                 return 0;
          234                         break;
          235                 case ADIRECT:
          236                 case ASTR:
          237                         if (np->addr != arg)
          238                                 return 0;
          239                         break;
          240                 default:
          241                         abort();
          242                 }
          243         }
          244 
          245         return *args == NULL;
          246 }
          247 
          248 Node *
          249 moperand(void)
          250 {
          251 }
          252 
          253 static int
          254 reg8toint(Node *np)
          255 {
          256         switch (np->sym->value) {
          257         case AREG_AL: return 0;
          258         case AREG_CL: return 1;
          259         case AREG_DL: return 2;
          260         case AREG_BL: return 3;
          261         case AREG_AH: return 4;
          262         case AREG_CH: return 5;
          263         case AREG_DH: return 6;
          264         case AREG_BH: return 7;
          265         default:      abort();
          266         }
          267 }
          268 
          269 static int
          270 reg16toint(Node *np)
          271 {
          272         switch (np->sym->value) {
          273         case AREG_AX: return 0;
          274         case AREG_CX: return 1;
          275         case AREG_DX: return 2;
          276         case AREG_BX: return 3;
          277         case AREG_SP: return 4;
          278         case AREG_BP: return 5;
          279         case AREG_SI: return 6;
          280         case AREG_DI: return 7;
          281         default:        abort();
          282         }
          283 }
          284 
          285 static int
          286 reg32toint(Node *np)
          287 {
          288         switch (np->sym->value) {
          289         case AREG_EAX: return 0;
          290         case AREG_ECX: return 1;
          291         case AREG_EDX: return 2;
          292         case AREG_EBX: return 3;
          293         case AREG_ESP: return 4;
          294         case AREG_EBP: return 5;
          295         case AREG_ESI: return 6;
          296         case AREG_EDI: return 7;
          297         default:        abort();
          298         }
          299 }
          300 
          301 void
          302 reg8_reg8(Op *op, Node **args)
          303 {
          304         int src, dst;
          305         char buf[op->size];
          306 
          307         src = reg8toint(args[0]);
          308         dst = reg8toint(args[1]);
          309         memcpy(buf, op->bytes, op->size - 1);
          310         buf[op->size - 1] = addrbyte(REG_MODE, src, dst);
          311         emit(buf, op->size);
          312 }
          313 
          314 void
          315 imm8_reg8(Op *op, Node **args)
          316 {
          317         int src, dst;
          318         char buf[op->size];
          319 
          320         src = (*args)->sym->value;
          321         dst = reg8toint(args[1]);
          322         memcpy(buf, op->bytes, op->size - 2);
          323         buf[op->size - 2] = addrbyte(REG_MODE, 0, dst);
          324         buf[op->size - 1] = src;
          325         emit(buf, op->size);
          326 }
          327 
          328 
          329 void
          330 reg16_reg16(Op *op, Node **args)
          331 {
          332         int src, dst;
          333         char buf[op->size];
          334 
          335         src = reg16toint(args[0]);
          336         dst = reg16toint(args[1]);
          337         memcpy(buf, op->bytes, op->size - 1);
          338         buf[op->size - 1] = addrbyte(REG_MODE, src, dst);
          339         emit(buf, op->size);
          340 }
          341 
          342 
          343 void
          344 reg32_reg32(Op *op, Node **args)
          345 {
          346         int src, dst;
          347         char buf[op->size];
          348 
          349         src = reg32toint(args[0]);
          350         dst = reg32toint(args[1]);
          351         memcpy(buf, op->bytes, op->size - 1);
          352         buf[op->size - 1] = addrbyte(REG_MODE, src, dst);
          353         emit(buf, op->size);
          354 }