what is an identity vector? Is this (0, 0, 0, 1) or (1, 1, 1, 1)/vone?
My bad I didnt test this function well enough to notice what it really does, but I did a few more tests and here's what I found:
This function initializes a vector to identity, but it does so according to the layout of the appropriate matrix. In the register display, I see this:
vidt_q Q_C000
vidt_q Q_C010
1 0 0 0
0 1 0 0
x x x x
x x x x
Now with Q_R000 and Q_R0001, i get:
1 0 x x
0 1 x x
0 0 x x
0 0 x x
Think of this as setting a row or column of a matrix to identity. The same behavior applies to triple and pair as well.
and heres another batch of ops:
Code: Select all
/*
+-------------------------------------+----+--------------+---+--------------+
|31 16 | 15 | 14 8 | 7 | 6 0 |
+-------------------------------------+----+--------------+---+--------------+
| opcode 0xd0010000 (s) | 0 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0xd0010080 (p) | 0 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
| opcode 0xd0018000 (t) | 1 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0xd0018080 (q) | 1 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
+-------------------------------------+----+--------------+---+--------------+
AbsoluteValue.Single/Pair/Triple/Quad
vabs.s %vfpu_rd, %vfpu_rs ; Absolute Value Single
vabs.p %vfpu_rd, %vfpu_rs ; Absolute Value Pair
vabs.t %vfpu_rd, %vfpu_rs ; Absolute Value Triple
vabs.q %vfpu_rd, %vfpu_rs ; Absolute Value Quad
%vfpu_rd: VFPU Vector Destination Register (m[p|t|q]reg 0..127)
%vfpu_rs: VFPU Vector Source Register (m[p|t|q]reg 0..127)
vfpu_regs[%vfpu_rd] <- abs(vfpu_regs[%vfpu_rs])
*/
#define vabs_s(vfpu_rd,vfpu_rs) (0xd0010000 | ((vfpu_rs) << 8) | (vfpu_rd))
#define vabs_p(vfpu_rd,vfpu_rs) (0xd0010080 | ((vfpu_rs) << 8) | (vfpu_rd))
#define vabs_t(vfpu_rd,vfpu_rs) (0xd0018000 | ((vfpu_rs) << 8) | (vfpu_rd))
#define vabs_q(vfpu_rd,vfpu_rs) (0xd0018080 | ((vfpu_rs) << 8) | (vfpu_rd))
/*
+-------------------------------------+----+--------------+---+--------------+
|31 16 | 15 | 14 8 | 7 | 6 0 |
+-------------------------------------+----+--------------+---+--------------+
| opcode 0xd002 (s) | 0 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0xd002 (p) | 0 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
| opcode 0xd002 (t) | 1 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0xd002 (q) | 1 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
+-------------------------------------+----+--------------+---+--------------+
Negate.Single/Pair/Triple/Quad
vneg.s %vfpu_rd, %vfpu_rs ; Negate Single
vneg.p %vfpu_rd, %vfpu_rs ; Negate Pair
vneg.t %vfpu_rd, %vfpu_rs ; Negate Triple
vneg.q %vfpu_rd, %vfpu_rs ; Negate Quad
%vfpu_rd: VFPU Vector Destination Register (m[p|t|q]reg 0..127)
%vfpu_rs: VFPU Vector Source Register (m[p|t|q]reg 0..127)
vfpu_regs[%vfpu_rd] <- -vfpu_regs[%vfpu_rs]
*/
#define vneg_s(vfpu_rd,vfpu_rs) (0xd0020000 | ((vfpu_rs) << 8) | (vfpu_rd))
#define vneg_p(vfpu_rd,vfpu_rs) (0xd0020080 | ((vfpu_rs) << 8) | (vfpu_rd))
#define vneg_t(vfpu_rd,vfpu_rs) (0xd0028000 | ((vfpu_rs) << 8) | (vfpu_rd))
#define vneg_q(vfpu_rd,vfpu_rs) (0xd0028080 | ((vfpu_rs) << 8) | (vfpu_rd))
/*
+-------------------------------------+----+--------------+---+--------------+
|31 16 | 15 | 14 8 | 7 | 6 0 |
+-------------------------------------+----+--------------+---+--------------+
| opcode 0xd04a (s) | 0 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0xd04a (p) | 0 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
| opcode 0xd04a (t) | 1 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0xd04a (q) | 1 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
+-------------------------------------+----+--------------+---+--------------+
Sign.Single/Pair/Triple/Quad
vsgn.s %vfpu_rd, %vfpu_rs ; Get Sign Single
vsgn.p %vfpu_rd, %vfpu_rs ; Get Sign Pair
vsgn.t %vfpu_rd, %vfpu_rs ; Get Sign Triple
vsgn.q %vfpu_rd, %vfpu_rs ; Get Sign Quad
%vfpu_rd: VFPU Vector Destination Register (m[p|t|q]reg 0..127)
%vfpu_rs: VFPU Vector Source Register (m[p|t|q]reg 0..127)
vfpu_regs[%vfpu_rd] <- sign(vfpu_regs[%vfpu_rs])
this will set rd values to 1 or -1, depending on sign of input values
*/
#define vsgn_s(vfpu_rd,vfpu_rs) (0xd04a0000 | ((vfpu_rs) << 8) | (vfpu_rd))
#define vsgn_p(vfpu_rd,vfpu_rs) (0xd04a0080 | ((vfpu_rs) << 8) | (vfpu_rd))
#define vsgn_t(vfpu_rd,vfpu_rs) (0xd04a8000 | ((vfpu_rs) << 8) | (vfpu_rd))
#define vsgn_q(vfpu_rd,vfpu_rs) (0xd04a8080 | ((vfpu_rs) << 8) | (vfpu_rd))
/*
+----------------------+--------------+----+--------------+---+--------------+
|31 23 | 22 16 | 15 | 14 8 | 7 | 6 0 |
+----------------------+--------------+----+--------------+---+--------------+
| opcode 0x6d0 (s) | vfpu_rt[6-0] | 0 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0x6d0 (p) | vfpu_rt[6-0] | 0 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
| opcode 0x6d0 (t) | vfpu_rt[6-0] | 1 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0x6d0 (q) | vfpu_rt[6-0] | 1 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
+----------------------+--------------+----+--------------+---+--------------+
VectorMin.Single/Pair/Triple/Quad
vmin.s %vfpu_rd, %vfpu_rs, %vfpu_rt ; Get Minimum Value Single
vmin.p %vfpu_rd, %vfpu_rs, %vfpu_rt ; Get Minimum Value Pair
vmin.t %vfpu_rd, %vfpu_rs, %vfpu_rt ; Get Minimum Value Triple
vmin.q %vfpu_rd, %vfpu_rs, %vfpu_rt ; Get Minimum Value Quad
%vfpu_rt: VFPU Vector Source Register (sreg 0..127)
%vfpu_rs: VFPU Vector Source Register ([p|t|q]reg 0..127)
%vfpu_rd: VFPU Vector Destination Register ([s|p|t|q]reg 0..127)
vfpu_regs[%vfpu_rd] <- min(vfpu_regs[%vfpu_rs], vfpu_reg[%vfpu_rt])
*/
#define vmin_s(vfpu_rd,vfpu_rs,vfpu_rt) (0x6D000000 | ((vfpu_rt) << 16) | ((vfpu_rs) << 8) | (vfpu_rd))
#define vmin_p(vfpu_rd,vfpu_rs,vfpu_rt) (0x6D000080 | ((vfpu_rt) << 16) | ((vfpu_rs) << 8) | (vfpu_rd))
#define vmin_t(vfpu_rd,vfpu_rs,vfpu_rt) (0x6D008000 | ((vfpu_rt) << 16) | ((vfpu_rs) << 8) | (vfpu_rd))
#define vmin_q(vfpu_rd,vfpu_rs,vfpu_rt) (0x6D008080 | ((vfpu_rt) << 16) | ((vfpu_rs) << 8) | (vfpu_rd))
/*
+----------------------+--------------+----+--------------+---+--------------+
|31 23 | 22 16 | 15 | 14 8 | 7 | 6 0 |
+----------------------+--------------+----+--------------+---+--------------+
| opcode 0x6d8 (s) | vfpu_rt[6-0] | 0 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0x6d8 (p) | vfpu_rt[6-0] | 0 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
| opcode 0x6d8 (t) | vfpu_rt[6-0] | 1 | vfpu_rs[6-0] | 0 | vfpu_rd[6-0] |
| opcode 0x6d8 (q) | vfpu_rt[6-0] | 1 | vfpu_rs[6-0] | 1 | vfpu_rd[6-0] |
+----------------------+--------------+----+--------------+---+--------------+
VectorMax.Single/Pair/Triple/Quad
vmax.s %vfpu_rd, %vfpu_rs, %vfpu_rt ; Get Maximum Value Single
vmax.p %vfpu_rd, %vfpu_rs, %vfpu_rt ; Get Maximum Value Pair
vmax.t %vfpu_rd, %vfpu_rs, %vfpu_rt ; Get Maximum Value Triple
vmax.q %vfpu_rd, %vfpu_rs, %vfpu_rt ; Get Maximum Value Quad
%vfpu_rt: VFPU Vector Source Register (sreg 0..127)
%vfpu_rs: VFPU Vector Source Register ([p|t|q]reg 0..127)
%vfpu_rd: VFPU Vector Destination Register ([s|p|t|q]reg 0..127)
vfpu_regs[%vfpu_rd] <- max(vfpu_regs[%vfpu_rs], vfpu_reg[%vfpu_rt])
*/
#define vmax_s(vfpu_rd,vfpu_rs,vfpu_rt) (0x6D800000 | ((vfpu_rt) << 16) | ((vfpu_rs) << 8) | (vfpu_rd))
#define vmax_p(vfpu_rd,vfpu_rs,vfpu_rt) (0x6D800080 | ((vfpu_rt) << 16) | ((vfpu_rs) << 8) | (vfpu_rd))
#define vmax_t(vfpu_rd,vfpu_rs,vfpu_rt) (0x6D808000 | ((vfpu_rt) << 16) | ((vfpu_rs) << 8) | (vfpu_rd))
#define vmax_q(vfpu_rd,vfpu_rs,vfpu_rt) (0x6D808080 | ((vfpu_rt) << 16) | ((vfpu_rs) << 8) | (vfpu_rd))
I'm working on v(h)tfm4/3/2, these are the vector*matrix ops, almost have a working set of functions to setup x/y/z rotation, projection matrix and concat matrix functions.
I need very specific info on vmmul. According to mips_dis.c, the vmmul instruction recieves special treatment and requires bit 13 (RXC bit) to be inverted...Im not sure how to do that, or what purpose that serves..can someone enlighten us on this?