rtasm_ppc_spe.c

Go to the documentation of this file.
00001 /*
00002  * (C) Copyright IBM Corporation 2008
00003  * All Rights Reserved.
00004  *
00005  * Permission is hereby granted, free of charge, to any person obtaining a
00006  * copy of this software and associated documentation files (the "Software"),
00007  * to deal in the Software without restriction, including without limitation
00008  * on the rights to use, copy, modify, merge, publish, distribute, sub
00009  * license, and/or sell copies of the Software, and to permit persons to whom
00010  * the Software is furnished to do so, subject to the following conditions:
00011  *
00012  * The above copyright notice and this permission notice (including the next
00013  * paragraph) shall be included in all copies or substantial portions of the
00014  * Software.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
00019  * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
00020  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
00021  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
00022  * USE OR OTHER DEALINGS IN THE SOFTWARE.
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     /* Conservatively treat R0 - R2 and R80 - R127 as non-volatile.
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 /* Hint-for-branch instructions
00444  */
00445 #if 0
00446 hbr;
00447 hbra;
00448 hbrr;
00449 #endif
00450 
00451 
00452 /* Control instructions
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 /* GALLIUM_CELL */

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4