target/sparc: Fix ARRAY8
Follow the Oracle Sparc 2015 implementation note and bound the input value of N to 5 from the lower 3 bits of rs2. Spell out all of the intermediate values, matching the diagram in the manual. Fix extraction of upper_x and upper_y for N=0. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
e6e903db6a
commit
fa9079a86d
@ -21,25 +21,42 @@
|
|||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "exec/helper-proto.h"
|
#include "exec/helper-proto.h"
|
||||||
|
|
||||||
/* This function uses non-native bit order */
|
target_ulong helper_array8(target_ulong rs1, target_ulong rs2)
|
||||||
#define GET_FIELD(X, FROM, TO) \
|
|
||||||
((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
|
|
||||||
|
|
||||||
/* This function uses the order in the manuals, i.e. bit 0 is 2^0 */
|
|
||||||
#define GET_FIELD_SP(X, FROM, TO) \
|
|
||||||
GET_FIELD(X, 63 - (TO), 63 - (FROM))
|
|
||||||
|
|
||||||
target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize)
|
|
||||||
{
|
{
|
||||||
return (GET_FIELD_SP(pixel_addr, 60, 63) << (17 + 2 * cubesize)) |
|
/*
|
||||||
(GET_FIELD_SP(pixel_addr, 39, 39 + cubesize - 1) << (17 + cubesize)) |
|
* From Oracle SPARC Architecture 2015:
|
||||||
(GET_FIELD_SP(pixel_addr, 17 + cubesize - 1, 17) << 17) |
|
* Architecturally, an illegal R[rs2] value (>5) causes the array
|
||||||
(GET_FIELD_SP(pixel_addr, 56, 59) << 13) |
|
* instructions to produce undefined results. For historic reference,
|
||||||
(GET_FIELD_SP(pixel_addr, 35, 38) << 9) |
|
* past implementations of these instructions have ignored R[rs2]{63:3}
|
||||||
(GET_FIELD_SP(pixel_addr, 13, 16) << 5) |
|
* and have treated R[rs2] values of 6 and 7 as if they were 5.
|
||||||
(((pixel_addr >> 55) & 1) << 4) |
|
*/
|
||||||
(GET_FIELD_SP(pixel_addr, 33, 34) << 2) |
|
target_ulong n = MIN(rs2 & 7, 5);
|
||||||
GET_FIELD_SP(pixel_addr, 11, 12);
|
|
||||||
|
target_ulong x_int = (rs1 >> 11) & 0x7ff;
|
||||||
|
target_ulong y_int = (rs1 >> 33) & 0x7ff;
|
||||||
|
target_ulong z_int = rs1 >> 55;
|
||||||
|
|
||||||
|
target_ulong lower_x = x_int & 3;
|
||||||
|
target_ulong lower_y = y_int & 3;
|
||||||
|
target_ulong lower_z = z_int & 1;
|
||||||
|
|
||||||
|
target_ulong middle_x = (x_int >> 2) & 15;
|
||||||
|
target_ulong middle_y = (y_int >> 2) & 15;
|
||||||
|
target_ulong middle_z = (z_int >> 1) & 15;
|
||||||
|
|
||||||
|
target_ulong upper_x = (x_int >> 6) & ((1 << n) - 1);
|
||||||
|
target_ulong upper_y = (y_int >> 6) & ((1 << n) - 1);
|
||||||
|
target_ulong upper_z = z_int >> 5;
|
||||||
|
|
||||||
|
return (upper_z << (17 + 2 * n))
|
||||||
|
| (upper_y << (17 + n))
|
||||||
|
| (upper_x << 17)
|
||||||
|
| (middle_z << 13)
|
||||||
|
| (middle_y << 9)
|
||||||
|
| (middle_x << 5)
|
||||||
|
| (lower_z << 4)
|
||||||
|
| (lower_y << 2)
|
||||||
|
| lower_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HOST_BIG_ENDIAN
|
#if HOST_BIG_ENDIAN
|
||||||
|
Loading…
Reference in New Issue
Block a user