197 lines
3.6 KiB
C
197 lines
3.6 KiB
C
#include "qemu/osdep.h"
|
|
#include "qemu/log.h"
|
|
#include "cpu.h"
|
|
#include "exec/exec-all.h"
|
|
#include "qemu/host-utils.h"
|
|
#include "exec/helper-proto.h"
|
|
#include "translate.h"
|
|
|
|
static uint8_t reverse_bits(uint8_t b)
|
|
{
|
|
b = ((b & 0xf0) >> 4) | ((b & 0x0f) << 4);
|
|
b = ((b & 0xcc) >> 2) | ((b & 0x33) << 2);
|
|
b = ((b & 0xaa) >> 1) | ((b & 0x55) << 1);
|
|
return b;
|
|
}
|
|
|
|
typedef union {
|
|
uint8_t ub[8];
|
|
uint16_t uh[4];
|
|
uint32_t uw[2];
|
|
uint64_t uq;
|
|
int8_t sb[8];
|
|
int16_t sh[4];
|
|
int32_t sw[2];
|
|
int64_t sq;
|
|
} vec64;
|
|
|
|
uint64_t HELPER(packed_shuffle_i64)(uint64_t src1, uint64_t src2, uint64_t src3)
|
|
{
|
|
vec64 ret, s1, s2, s3;
|
|
unsigned int i;
|
|
|
|
s1.uq = src1;
|
|
s2.uq = src2;
|
|
s3.uq = src3;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
uint8_t desc = s3.ub[i];
|
|
int index = extract8(desc, 0, 3);
|
|
uint8_t byte;
|
|
|
|
if (desc < 0x80) {
|
|
if (desc & 0x08) {
|
|
byte = s1.ub[index];
|
|
} else {
|
|
byte = s2.ub[index];
|
|
}
|
|
|
|
switch(desc >> 5) {
|
|
case 0x1:
|
|
byte = reverse_bits(byte);
|
|
break;
|
|
case 0x2:
|
|
if ((byte & 0x80) != 0) {
|
|
byte = 0xff;
|
|
} else {
|
|
byte = 0;
|
|
}
|
|
break;
|
|
case 0x3:
|
|
if ((byte & 1) != 0) {
|
|
byte = 0xff;
|
|
} else {
|
|
byte = 0;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (desc & 0x10) {
|
|
byte = ~byte;
|
|
}
|
|
} else {
|
|
switch(desc >> 6) {
|
|
case 0xa:
|
|
byte = 0x7f;
|
|
break;
|
|
case 0xc:
|
|
byte = 0x80;
|
|
break;
|
|
case 0xe:
|
|
byte = 0xff;
|
|
break;
|
|
default:
|
|
byte = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ret.ub[i] = byte;
|
|
}
|
|
|
|
return ret.uq;
|
|
}
|
|
|
|
// FIXME: not tested
|
|
uint64_t HELPER(pcmpeqb)(uint64_t src1, uint64_t src2)
|
|
{
|
|
unsigned int i;
|
|
vec64 s1, s2, ret;
|
|
|
|
s1.uq = src1;
|
|
s2.uq = src2;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
if (s1.ub[i] == s2.ub[i]) {
|
|
ret.ub[i] = 0xff;
|
|
} else {
|
|
ret.ub[i] = 0;
|
|
}
|
|
}
|
|
|
|
return ret.uq;
|
|
}
|
|
|
|
uint64_t HELPER(pminub)(uint64_t src1, uint64_t src2)
|
|
{
|
|
unsigned int i;
|
|
vec64 s1, s2, ret;
|
|
|
|
s1.uq = src1;
|
|
s2.uq = src2;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
ret.ub[i] = MIN(s1.ub[i], s2.ub[i]);
|
|
}
|
|
|
|
return ret.uq;
|
|
}
|
|
|
|
uint64_t HELPER(pminsh)(uint64_t src1, uint64_t src2)
|
|
{
|
|
unsigned int i;
|
|
vec64 s1, s2, ret;
|
|
|
|
s1.uq = src1;
|
|
s2.uq = src2;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
ret.sh[i] = MIN(s1.sh[i], s2.sh[i]);
|
|
}
|
|
|
|
return ret.uq;
|
|
}
|
|
|
|
uint64_t HELPER(pmaxub)(uint64_t src1, uint64_t src2)
|
|
{
|
|
unsigned int i;
|
|
vec64 s1, s2, ret;
|
|
|
|
s1.uq = src1;
|
|
s2.uq = src2;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
ret.ub[i] = MAX(s1.ub[i], s2.ub[i]);
|
|
}
|
|
|
|
return ret.uq;
|
|
}
|
|
|
|
uint64_t HELPER(pmaxsh)(uint64_t src1, uint64_t src2)
|
|
{
|
|
unsigned int i;
|
|
vec64 s1, s2, ret;
|
|
|
|
s1.uq = src1;
|
|
s2.uq = src2;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
ret.sh[i] = MAX(s1.sh[i], s2.sh[i]);
|
|
}
|
|
|
|
return ret.uq;
|
|
}
|
|
|
|
uint64_t HELPER(pmovmskb)(uint64_t src1, uint64_t src2)
|
|
{
|
|
unsigned int i;
|
|
vec64 s1, s2;
|
|
uint16_t ret = 0;
|
|
|
|
s1.uq = src1;
|
|
s2.uq = src2;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
if (s1.sb[i] < 0) {
|
|
ret |= 1 << (i + 8);
|
|
}
|
|
if (s2.sb[i] < 0) {
|
|
ret |= 1 << i;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|