diff options
author | Brian Paul <[email protected]> | 2008-10-08 20:44:32 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2008-10-08 20:44:32 -0600 |
commit | d48a92e88040470f93e2186f8eb23e4797a09860 (patch) | |
tree | 7fbfd01dc04b42e42b4457eae507693ef8dc5f3b /src/gallium/auxiliary/rtasm | |
parent | a4e477433f485a39b5de448d0a9cb6f4bf9bb90f (diff) |
cell: implement function calls from shader code. fslight demo runs now.
Used for SIN, COS, EXP2, LOG2, POW instructions. TEX next.
Fixed some bugs in MIN, MAX, DP3, DP4, DPH instructions.
In rtasm code:
Special-case spe_lqd(), spe_stqd() functions so they take byte offsets but
low-order 4 bits are shifted out. This makes things consistant with SPU
assembly language conventions.
Added spe_get_registers_used() function.
Diffstat (limited to 'src/gallium/auxiliary/rtasm')
-rw-r--r-- | src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c | 76 | ||||
-rw-r--r-- | src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h | 11 |
2 files changed, 73 insertions, 14 deletions
diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c index c442b1f6aa2..9274bc5e3cd 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c @@ -174,9 +174,12 @@ reg_name(int reg) return "$lr"; default: { - static char buf[10]; - sprintf(buf, "$%d", reg); - return buf; + /* cycle through four buffers to handle multiple calls per printf */ + static char buf[4][10]; + static int b = 0; + b = (b + 1) % 4; + sprintf(buf[b], "$%d", reg); + return buf[b]; } } } @@ -269,15 +272,8 @@ static void emit_RI10(struct spe_function *p, unsigned op, unsigned rT, assert(p->num_inst <= p->max_inst); if (p->print) { indent(p); - if (strcmp(name, "spe_lqd") == 0 || - strcmp(name, "spe_stqd") == 0) { - printf("%s\t%s, %d(%s)\n", - rem_prefix(name), reg_name(rT), imm, reg_name(rA)); - } - else { - printf("%s\t%s, %s, 0x%x\n", - rem_prefix(name), reg_name(rT), reg_name(rA), imm); - } + printf("%s\t%s, %s, 0x%x\n", + rem_prefix(name), reg_name(rT), reg_name(rA), imm); } } @@ -379,6 +375,7 @@ void _name (struct spe_function *p, int imm) \ #include "rtasm_ppc_spe.h" + /** * Initialize an spe_function. * \param code_size size of instruction buffer to allocate, in bytes. @@ -513,6 +510,20 @@ void spe_release_register_set(struct spe_function *p) } +unsigned +spe_get_registers_used(const struct spe_function *p, ubyte used[]) +{ + unsigned i, num = 0; + /* only count registers in the range available to callers */ + for (i = 2; i < 80; i++) { + if (p->regs[i]) { + used[num++] = i; + } + } + return num; +} + + void spe_print_code(struct spe_function *p, boolean enable) { @@ -540,6 +551,46 @@ spe_comment(struct spe_function *p, int rel_indent, const char *s) /** + * Load quad word. + * NOTE: imm is in bytes and the least significant 4 bits must be zero! + */ +void spe_lqd(struct spe_function *p, unsigned rT, unsigned rA, int offset) +{ + const boolean pSave = p->print; + + p->print = FALSE; + assert(offset % 4 == 0); + emit_RI10(p, 0x034, rT, rA, offset >> 4, "spe_lqd"); + p->print = pSave; + + if (p->print) { + indent(p); + printf("lqd\t%s, %d(%s)\n", reg_name(rT), offset, reg_name(rA)); + } +} + + +/** + * Store quad word. + * NOTE: imm is in bytes and the least significant 4 bits must be zero! + */ +void spe_stqd(struct spe_function *p, unsigned rT, unsigned rA, int offset) +{ + const boolean pSave = p->print; + + p->print = FALSE; + assert(offset % 4 == 0); + emit_RI10(p, 0x024, rT, rA, offset >> 4, "spe_stqd"); + p->print = pSave; + + if (p->print) { + indent(p); + printf("stqd\t%s, %d(%s)\n", reg_name(rT), offset, reg_name(rA)); + } +} + + +/** * For branch instructions: * \param d if 1, disable interupts if branch is taken * \param e if 1, enable interupts if branch is taken @@ -764,6 +815,7 @@ spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui) spe_release_register(p, tmp_reg); } + /** * This function is constructed identically to spe_and_uint() above. * Changes to one should be made in the other. diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h index cd2e2454097..47dadb343c2 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h @@ -89,6 +89,9 @@ extern void spe_release_register(struct spe_function *p, int reg); extern void spe_allocate_register_set(struct spe_function *p); extern void spe_release_register_set(struct spe_function *p); +extern unsigned +spe_get_registers_used(const struct spe_function *p, ubyte used[]); + extern void spe_print_code(struct spe_function *p, boolean enable); extern void spe_indent(struct spe_function *p, int spaces); extern void spe_comment(struct spe_function *p, int rel_indent, const char *s); @@ -128,11 +131,9 @@ extern void spe_comment(struct spe_function *p, int rel_indent, const char *s); /* Memory load / store instructions */ -EMIT_RI10(spe_lqd, 0x034); EMIT_RR (spe_lqx, 0x1c4); EMIT_RI16(spe_lqa, 0x061); EMIT_RI16(spe_lqr, 0x067); -EMIT_RI10(spe_stqd, 0x024); EMIT_RR (spe_stqx, 0x144); EMIT_RI16(spe_stqa, 0x041); EMIT_RI16(spe_stqr, 0x047); @@ -290,6 +291,12 @@ EMIT_RI16(spe_brz, 0x040); EMIT_RI16(spe_brhnz, 0x046); EMIT_RI16(spe_brhz, 0x044); +extern void +spe_lqd(struct spe_function *p, unsigned rT, unsigned rA, int offset); + +extern void +spe_stqd(struct spe_function *p, unsigned rT, unsigned rA, int offset); + extern void spe_bi(struct spe_function *p, unsigned rA, int d, int e); extern void spe_iret(struct spe_function *p, unsigned rA, int d, int e); extern void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, |