I just updated the Wiki page talking about swizzling with a description of what swizzling means in terms of bit-level transformations on the offset. It's very simple: swizzling rotates the bits in the field between bit 4 and bit log2(width)+3. http://wiki.ps2dev.org/psp:ge_faq.
This is pretty easy to do in C with some masking and shifting, but I wonder if the PSP's MIPS has some bitfield rotation instructions which can simplify this operation? I seem to remember it has something like this.
MIPS bitfield rotation instruction?
The ALLEGREX CPU supports MIPS rotr and rotrv. GCC does a pretty good job of detecting a rotate, if you have code like this:
the compiler will convert that to to the appropiate rotr instruction.
Code: Select all
val = (val >> shift) | (val << 32 - shift)
Yeah, but it isn't a whole-word rotate. It's a rotate of the range of bits 4-N (N=5-11). It isn't very RISCy, but I was wondering if there were some instruction for doing this kind of rotate, or maybe some bitfield extraction/insertion instructions which might be helpful.
Is there any kind of available instruction set documentation for Allegrex or an Allegrex-like CPU?
Is there any kind of available instruction set documentation for Allegrex or an Allegrex-like CPU?
If you want bitfield extraction and insertion, check out ext and ins. The syntax for ext and ins are:
The opcode table that our assembler supports was back-engineered from the "official" PSP GCC compiler binaries floating around the net. Your best bet for real docs on ALLEGREX instructions is in various MIPS manuals for CPUs that also include those same instructions.
I do need to get to updating the Wiki with info on the ALLGREX instruction builtins that our GCC supports... here's a short list:
ext and ins builtins are missing because I haven't figured out how Sony implemented the builtins in their GCC.
Code: Select all
ext rt, rs, pos, size // Extract size bits from position pos in rs and store in rt
ins rt, rs, pos, size // Insert size bits starting from the LSB of rs into rt starting at position pos
I do need to get to updating the Wiki with info on the ALLGREX instruction builtins that our GCC supports... here's a short list:
Code: Select all
u32 __builtin_allegrex_bitrev(u32); // Reverse the bits in the given word
u32 __builtin_allegrex_wsbh(u32); // Swap halfwords (htons)
u32 __builtin_allegrex_wsbw(u32); // Swap words (htonl)
u32 __builtin_allegrex_clz(u32); // Count leading zeros
u32 __builtin_allegrex_clo(u32); // Count leading ones
u32 __builtin_allegrex_rotr(u32, u32); // Rotate right
u32 __builtin_allegrex_rotl(u32, u32); // Rotate left
u32 __builtin_allegrex_seb(u8); // Sign extend byte
u32 __builtin_allegrex_seh(u16); // Sign extend halfword
u32 __builtin_allegrex_min(u32, u32); // Minimum
u32 __builtin_allegrex_max(u32, u32); // Maximum
...
Hm, might be useful. What happens if pos+size > 31?mrbrown wrote:If you want bitfield extraction and insertion, check out ext and ins. The syntax for ext and ins are:Code: Select all
ext rt, rs, pos, size // Extract size bits from position pos in rs and store in rt ins rt, rs, pos, size // Insert size bits starting from the LSB of rs into rt starting at position pos