1#include <stdlib.h>23#include <scc/mach.h>4#include <scc/scc.h>56#include "../as.h"7#include "proc.h"89/*10 * This code is derived from PowerISA_V2.06B_V2_PUBLIC document.11 * All the names used in the specification are preserved in12 * this code.13 */1415static int16getclass(Node *np)17{18 if (np->addr != AREG)19 return 0;2021 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}5859int60match(Op *op, Node **args)61{62 unsigned char *p;63 int arg, class, rep, opt;64 Node *np;6566 if (!op->args)67 return args == NULL;6869 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;7576 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 }113114 return *args == NULL;115}116117Node *118moperand(void)119{120 abort();121}122123static void124emit_packed(unsigned long ins)125{126 unsigned char buff[4];127128 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 }139140 emit(buff, 4);141}142143void144i_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);150151 opcd = op->bytes[0];152 aa = op->bytes[1];153 lk = op->bytes[2];154155 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");162163 li = dst;164 li >>= 2;165 ins = opcd<<26 | li<<2 | aa<<1 | lk;166 emit_packed(ins);167}168169void170b_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);176177 opcd = op->bytes[0];178 aa = op->bytes[1];179 lk = op->bytes[2];180181 bo = args[0]->sym->value;182 bi = args[1]->sym->value;183184 dst = args[2]->sym->value;185 if (dst & 0x3)186 error("unaligned branch");187 if (aa)188 dst -= getpc() - 4;189190 if (dst < min || dst > max)191 error("out of range branch");192 bd = dst;193 bd >>= 2;194195 ins = opcd<<26 | bo<<21 | bi<<16 | bd<<11 | aa<<1 | lk;196 emit_packed(ins);197}198199void200sc_form(Op *op, Node **args)201{202 abort();203}204205void206d_form(Op *op, Node **args)207{208 abort();209}210211void212ds_form(Op *op, Node **args)213{214 abort();215}216217void218dq_form(Op *op, Node **args)219{220 abort();221}222223void224x_form(Op *op, Node **args)225{226 abort();227}228229void230xl_form(Op *op, Node **args)231{232 unsigned long ins, bo, bi, bh, lk;233 unsigned long opcd1, opcd2;234 long long dst;235236 opcd1 = op->bytes[0];237 opcd2 = op->bytes[1]<<8 | op->bytes[2];238 lk = op->bytes[3];239240 bo = args[0]->sym->value;241 bi = args[1]->sym->value;242 bh = args[2]->sym->value;243244 ins = opcd1<<26 | bo<<21 | bi<<16 | bh<<11 | opcd2<<1 | lk;245 emit_packed(ins);246}247248void249xfx_form(Op *op, Node **args)250{251 abort();252}253254void255xlfdorm_form(Op *op, Node **args)256{257 abort();258}259260void261xx1_form(Op *op, Node **args)262{263 abort();264}265266void267xx2_form(Op *op, Node **args)268{269 abort();270}271272void273xx3_form(Op *op, Node **args)274{275 abort();276}277278void279xx4_form(Op *op, Node **args)280{281 abort();282}283284void285xs_form(Op *op, Node **args)286{287 abort();288}289290void291xo_form(Op *op, Node **args)292{293 abort();294}295296void297a_form(Op *op, Node **args)298{299 abort();300}301302void303m_form(Op *op, Node **args)304{305 abort();306}307308void309md_form(Op *op, Node **args)310{311 abort();312}313314void315mds_form(Op *op, Node **args)316{317 abort();318}319320void321va_form(Op *op, Node **args)322{323 abort();324}325326void327vc_form(Op *op, Node **args)328{329 abort();330}331332void333vx_form(Op *op, Node **args)334{335 abort();336}337338void339evs_form(Op *op, Node **args)340{341 abort();342}343344void345z22_form(Op *op, Node **args)346{347 abort();348}349350void351z23_form(Op *op, Node **args)352{353 abort();354}