00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00032 #include "pipe/p_compiler.h"
00033 #include "util/u_memory.h"
00034 #include "rtasm_ppc_spe.h"
00035
00036 #ifdef GALLIUM_CELL
00037
00051 union spe_inst_RR {
00052 uint32_t bits;
00053 struct {
00054 unsigned op:11;
00055 unsigned rB:7;
00056 unsigned rA:7;
00057 unsigned rT:7;
00058 } inst;
00059 };
00060
00061
00065 union spe_inst_RRR {
00066 uint32_t bits;
00067 struct {
00068 unsigned op:4;
00069 unsigned rT:7;
00070 unsigned rB:7;
00071 unsigned rA:7;
00072 unsigned rC:7;
00073 } inst;
00074 };
00075
00076
00080 union spe_inst_RI7 {
00081 uint32_t bits;
00082 struct {
00083 unsigned op:11;
00084 unsigned i7:7;
00085 unsigned rA:7;
00086 unsigned rT:7;
00087 } inst;
00088 };
00089
00090
00094 union spe_inst_RI8 {
00095 uint32_t bits;
00096 struct {
00097 unsigned op:10;
00098 unsigned i8:8;
00099 unsigned rA:7;
00100 unsigned rT:7;
00101 } inst;
00102 };
00103
00104
00108 union spe_inst_RI10 {
00109 uint32_t bits;
00110 struct {
00111 unsigned op:8;
00112 unsigned i10:10;
00113 unsigned rA:7;
00114 unsigned rT:7;
00115 } inst;
00116 };
00117
00118
00122 union spe_inst_RI16 {
00123 uint32_t bits;
00124 struct {
00125 unsigned op:9;
00126 unsigned i16:16;
00127 unsigned rT:7;
00128 } inst;
00129 };
00130
00131
00135 union spe_inst_RI18 {
00136 uint32_t bits;
00137 struct {
00138 unsigned op:7;
00139 unsigned i18:18;
00140 unsigned rT:7;
00141 } inst;
00142 };
00146 static void emit_RR(struct spe_function *p, unsigned op, unsigned rT,
00147 unsigned rA, unsigned rB)
00148 {
00149 union spe_inst_RR inst;
00150 inst.inst.op = op;
00151 inst.inst.rB = rB;
00152 inst.inst.rA = rA;
00153 inst.inst.rT = rT;
00154 p->store[p->num_inst++] = inst.bits;
00155 assert(p->num_inst <= p->max_inst);
00156 }
00157
00158
00159 static void emit_RRR(struct spe_function *p, unsigned op, unsigned rT,
00160 unsigned rA, unsigned rB, unsigned rC)
00161 {
00162 union spe_inst_RRR inst;
00163 inst.inst.op = op;
00164 inst.inst.rT = rT;
00165 inst.inst.rB = rB;
00166 inst.inst.rA = rA;
00167 inst.inst.rC = rC;
00168 p->store[p->num_inst++] = inst.bits;
00169 assert(p->num_inst <= p->max_inst);
00170 }
00171
00172
00173 static void emit_RI7(struct spe_function *p, unsigned op, unsigned rT,
00174 unsigned rA, int imm)
00175 {
00176 union spe_inst_RI7 inst;
00177 inst.inst.op = op;
00178 inst.inst.i7 = imm;
00179 inst.inst.rA = rA;
00180 inst.inst.rT = rT;
00181 p->store[p->num_inst++] = inst.bits;
00182 assert(p->num_inst <= p->max_inst);
00183 }
00184
00185
00186
00187 static void emit_RI8(struct spe_function *p, unsigned op, unsigned rT,
00188 unsigned rA, int imm)
00189 {
00190 union spe_inst_RI8 inst;
00191 inst.inst.op = op;
00192 inst.inst.i8 = imm;
00193 inst.inst.rA = rA;
00194 inst.inst.rT = rT;
00195 p->store[p->num_inst++] = inst.bits;
00196 assert(p->num_inst <= p->max_inst);
00197 }
00198
00199
00200
00201 static void emit_RI10(struct spe_function *p, unsigned op, unsigned rT,
00202 unsigned rA, int imm)
00203 {
00204 union spe_inst_RI10 inst;
00205 inst.inst.op = op;
00206 inst.inst.i10 = imm;
00207 inst.inst.rA = rA;
00208 inst.inst.rT = rT;
00209 p->store[p->num_inst++] = inst.bits;
00210 assert(p->num_inst <= p->max_inst);
00211 }
00212
00213
00214 static void emit_RI16(struct spe_function *p, unsigned op, unsigned rT,
00215 int imm)
00216 {
00217 union spe_inst_RI16 inst;
00218 inst.inst.op = op;
00219 inst.inst.i16 = imm;
00220 inst.inst.rT = rT;
00221 p->store[p->num_inst++] = inst.bits;
00222 assert(p->num_inst <= p->max_inst);
00223 }
00224
00225
00226 static void emit_RI18(struct spe_function *p, unsigned op, unsigned rT,
00227 int imm)
00228 {
00229 union spe_inst_RI18 inst;
00230 inst.inst.op = op;
00231 inst.inst.i18 = imm;
00232 inst.inst.rT = rT;
00233 p->store[p->num_inst++] = inst.bits;
00234 assert(p->num_inst <= p->max_inst);
00235 }
00236
00237
00238
00239
00240 #define EMIT_(_name, _op) \
00241 void _name (struct spe_function *p, unsigned rT) \
00242 { \
00243 emit_RR(p, _op, rT, 0, 0); \
00244 }
00245
00246 #define EMIT_R(_name, _op) \
00247 void _name (struct spe_function *p, unsigned rT, unsigned rA) \
00248 { \
00249 emit_RR(p, _op, rT, rA, 0); \
00250 }
00251
00252 #define EMIT_RR(_name, _op) \
00253 void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB) \
00254 { \
00255 emit_RR(p, _op, rT, rA, rB); \
00256 }
00257
00258 #define EMIT_RRR(_name, _op) \
00259 void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB, unsigned rC) \
00260 { \
00261 emit_RRR(p, _op, rT, rA, rB, rC); \
00262 }
00263
00264 #define EMIT_RI7(_name, _op) \
00265 void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
00266 { \
00267 emit_RI7(p, _op, rT, rA, imm); \
00268 }
00269
00270 #define EMIT_RI8(_name, _op, bias) \
00271 void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
00272 { \
00273 emit_RI8(p, _op, rT, rA, bias - imm); \
00274 }
00275
00276 #define EMIT_RI10(_name, _op) \
00277 void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
00278 { \
00279 emit_RI10(p, _op, rT, rA, imm); \
00280 }
00281
00282 #define EMIT_RI16(_name, _op) \
00283 void _name (struct spe_function *p, unsigned rT, int imm) \
00284 { \
00285 emit_RI16(p, _op, rT, imm); \
00286 }
00287
00288 #define EMIT_RI18(_name, _op) \
00289 void _name (struct spe_function *p, unsigned rT, int imm) \
00290 { \
00291 emit_RI18(p, _op, rT, imm); \
00292 }
00293
00294 #define EMIT_I16(_name, _op) \
00295 void _name (struct spe_function *p, int imm) \
00296 { \
00297 emit_RI16(p, _op, 0, imm); \
00298 }
00299
00300 #include "rtasm_ppc_spe.h"
00301
00302
00307 void spe_init_func(struct spe_function *p, unsigned code_size)
00308 {
00309 p->store = align_malloc(code_size, 16);
00310 p->num_inst = 0;
00311 p->max_inst = code_size / SPE_INST_SIZE;
00312
00313
00314
00315 p->regs[0] = ~7;
00316 p->regs[1] = (1U << (80 - 64)) - 1;
00317 }
00318
00319
00320 void spe_release_func(struct spe_function *p)
00321 {
00322 assert(p->num_inst <= p->max_inst);
00323 if (p->store != NULL) {
00324 align_free(p->store);
00325 }
00326 p->store = NULL;
00327 }
00328
00329
00334 int spe_allocate_available_register(struct spe_function *p)
00335 {
00336 unsigned i;
00337 for (i = 0; i < SPE_NUM_REGS; i++) {
00338 const uint64_t mask = (1ULL << (i % 64));
00339 const unsigned idx = i / 64;
00340
00341 assert(idx < 2);
00342 if ((p->regs[idx] & mask) != 0) {
00343 p->regs[idx] &= ~mask;
00344 return i;
00345 }
00346 }
00347
00348 return -1;
00349 }
00350
00351
00355 int spe_allocate_register(struct spe_function *p, int reg)
00356 {
00357 const unsigned idx = reg / 64;
00358 const unsigned bit = reg % 64;
00359
00360 assert(reg < SPE_NUM_REGS);
00361 assert((p->regs[idx] & (1ULL << bit)) != 0);
00362
00363 p->regs[idx] &= ~(1ULL << bit);
00364 return reg;
00365 }
00366
00367
00371 void spe_release_register(struct spe_function *p, int reg)
00372 {
00373 const unsigned idx = reg / 64;
00374 const unsigned bit = reg % 64;
00375
00376 assert(idx < 2);
00377
00378 assert(reg < SPE_NUM_REGS);
00379 assert((p->regs[idx] & (1ULL << bit)) == 0);
00380
00381 p->regs[idx] |= (1ULL << bit);
00382 }
00383
00384
00393 void spe_bi(struct spe_function *p, unsigned rA, int d, int e)
00394 {
00395 emit_RI7(p, 0x1a8, 0, rA, (d << 5) | (e << 4));
00396 }
00397
00399 void spe_iret(struct spe_function *p, unsigned rA, int d, int e)
00400 {
00401 emit_RI7(p, 0x1aa, 0, rA, (d << 5) | (e << 4));
00402 }
00403
00405 void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, int d,
00406 int e)
00407 {
00408 emit_RI7(p, 0x1ab, rT, rA, (d << 5) | (e << 4));
00409 }
00410
00412 void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA, int d,
00413 int e)
00414 {
00415 emit_RI7(p, 0x1a9, rT, rA, (d << 5) | (e << 4));
00416 }
00417
00419 void spe_biz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
00420 {
00421 emit_RI7(p, 0x128, rT, rA, (d << 5) | (e << 4));
00422 }
00423
00425 void spe_binz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
00426 {
00427 emit_RI7(p, 0x129, rT, rA, (d << 5) | (e << 4));
00428 }
00429
00431 void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
00432 {
00433 emit_RI7(p, 0x12a, rT, rA, (d << 5) | (e << 4));
00434 }
00435
00437 void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
00438 {
00439 emit_RI7(p, 0x12b, rT, rA, (d << 5) | (e << 4));
00440 }
00441
00442
00443
00444
00445 #if 0
00446 hbr;
00447 hbra;
00448 hbrr;
00449 #endif
00450
00451
00452
00453
00454 #if 0
00455 stop;
00456 EMIT_RR (spe_stopd, 0x140);
00457 EMIT_ (spe_lnop, 0x001);
00458 EMIT_ (spe_nop, 0x201);
00459 sync;
00460 EMIT_ (spe_dsync, 0x003);
00461 EMIT_R (spe_mfspr, 0x00c);
00462 EMIT_R (spe_mtspr, 0x10c);
00463 #endif
00464
00465
00473 void
00474 spe_load_float(struct spe_function *p, unsigned rT, float x)
00475 {
00476 if (x == 0.0f) {
00477 spe_il(p, rT, 0x0);
00478 }
00479 else if (x == 0.5f) {
00480 spe_ilhu(p, rT, 0x3f00);
00481 }
00482 else if (x == 1.0f) {
00483 spe_ilhu(p, rT, 0x3f80);
00484 }
00485 else if (x == -1.0f) {
00486 spe_ilhu(p, rT, 0xbf80);
00487 }
00488 else {
00489 union {
00490 float f;
00491 unsigned u;
00492 } bits;
00493 bits.f = x;
00494 spe_ilhu(p, rT, bits.u >> 16);
00495 spe_iohl(p, rT, bits.u & 0xffff);
00496 }
00497 }
00498
00499
00500 void
00501 spe_load_int(struct spe_function *p, unsigned rT, int i)
00502 {
00503 if (-32768 <= i && i <= 32767) {
00504 spe_il(p, rT, i);
00505 }
00506 else {
00507 spe_ilhu(p, rT, i >> 16);
00508 spe_iohl(p, rT, i & 0xffff);
00509 }
00510 }
00511
00512
00513 void
00514 spe_splat(struct spe_function *p, unsigned rT, unsigned rA)
00515 {
00516 spe_ila(p, rT, 66051);
00517 spe_shufb(p, rT, rA, rA, rT);
00518 }
00519
00520
00521 void
00522 spe_complement(struct spe_function *p, unsigned rT)
00523 {
00524 spe_nor(p, rT, rT, rT);
00525 }
00526
00527
00528 void
00529 spe_move(struct spe_function *p, unsigned rT, unsigned rA)
00530 {
00531 spe_ori(p, rT, rA, 0);
00532 }
00533
00534
00535 void
00536 spe_zero(struct spe_function *p, unsigned rT)
00537 {
00538 spe_xor(p, rT, rT, rT);
00539 }
00540
00541
00542 #endif