Browse Source

rvp: fix shift w/ or w/o saturation

Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
pull/2310/head
Chih-Min Chao 3 months ago
parent
commit
4caf3468b9
  1. 2
      riscv/insns/pssh1sadd_w.h
  2. 4
      riscv/insns/pssha_hs.h
  3. 4
      riscv/insns/pssha_ws.h
  4. 2
      riscv/insns/psshar_hs.h
  5. 2
      riscv/insns/psshar_ws.h
  6. 13
      riscv/insns/psshl_dhs.h
  7. 13
      riscv/insns/psshl_dws.h
  8. 13
      riscv/insns/psshl_hs.h
  9. 13
      riscv/insns/psshl_ws.h
  10. 16
      riscv/insns/psshlr_dhs.h
  11. 16
      riscv/insns/psshlr_dws.h
  12. 16
      riscv/insns/psshlr_hs.h
  13. 16
      riscv/insns/psshlr_ws.h
  14. 13
      riscv/insns/shl.h
  15. 15
      riscv/insns/shlr.h
  16. 19
      riscv/insns/sshar.h
  17. 17
      riscv/insns/sshl.h
  18. 22
      riscv/insns/sshlr.h

2
riscv/insns/pssh1sadd_w.h

@ -1,5 +1,5 @@
require_rv64;
P_RD_RS1_RS2_LOOP(32, 32, 32, {
p_rd = P_SAT(32, P_SAT(32, p_rs1 << 1) + p_rs2);
p_rd = P_SAT(32, P_SAT(32, (int64_t)p_rs1 << 1) + p_rs2);
}
)

4
riscv/insns/pssha_hs.h

@ -3,11 +3,11 @@ P_RD_RS1_LOOP(16, 16, {
if (p_rs1 == 0)
p_rd = 0;
else if (sshamt >= 16) {
p_rd = (p_rs1 & 0x8000) ? 0x8000 : 0x7fff;
p_rd = (p_rs1 & 0x8000) ? INT16_MIN : INT16_MAX;
P.set_vxsat();
}
else if (sshamt <= -16)
p_rd = (p_rs1 & 0x8000) ? 0xffff : 0;
p_rd = (p_rs1 & 0x8000) ? (int16_t)UINT16_MAX : 0;
else
p_rd = sshamt >= 0 ? P_SAT(16, sext32(p_rs1) << sshamt) : (p_rs1 >> -sshamt);
})

4
riscv/insns/pssha_ws.h

@ -4,11 +4,11 @@ P_RD_RS1_LOOP(32, 32, {
if (p_rs1 == 0)
p_rd = 0;
else if (sshamt >= 32) {
p_rd = (p_rs1 & 0x80000000) ? 0x80000000 : 0x7fffffff;
p_rd = (p_rs1 & 0x80000000) ? INT32_MIN : INT32_MAX;
P.set_vxsat();
}
else if (sshamt <= -32)
p_rd = (p_rs1 & 0x80000000) ? 0xffffffff : 0;
p_rd = (p_rs1 & 0x80000000) ? (int32_t)UINT32_MAX : 0;
else
p_rd = sshamt >= 0 ? P_SAT(32, sext32(p_rs1) << sshamt) : (p_rs1 >> -sshamt);
}

2
riscv/insns/psshar_hs.h

@ -3,7 +3,7 @@ P_RD_RS1_LOOP(16, 16, {
if (p_rs1 == 0)
p_rd = 0;
else if (sshamt >= 16) {
p_rd = (p_rs1 & 0x8000) ? 0x8000 : 0x7fff;
p_rd = (p_rs1 & 0x8000) ? INT16_MIN : INT16_MAX;
P.set_vxsat();
}
else if (sshamt <= -16)

2
riscv/insns/psshar_ws.h

@ -4,7 +4,7 @@ P_RD_RS1_LOOP(32, 32, {
if (p_rs1 == 0)
p_rd = 0;
else if (sshamt >= 32) {
p_rd = (p_rs1 & 0x80000000) ? 0x80000000 : 0x7fffffff;
p_rd = (p_rs1 & 0x80000000) ? INT32_MIN : INT32_MAX;
P.set_vxsat();
}
else if (sshamt <= -32)

13
riscv/insns/psshl_dhs.h

@ -1,16 +1,13 @@
require_rv32;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
P_RD_RS1_DW_LOOP(16, 16, {
if (sshamt < 0) {
if (sshamt <= -16)
p_rd = 0;
else
p_rd = (uint16_t)p_rs1 >> (-sshamt);
p_rd = (uint32_t)(uint16_t)p_rs1 >> std::min(-sshamt, 16);
} else {
uint32_t shx = (sshamt >= 16) ? ((uint32_t)(uint16_t)p_rs1 << 16) : ((uint32_t)(uint16_t)p_rs1 << sshamt);
if (shx > 0xFFFF) {
uint32_t shx = (uint32_t)(uint16_t)p_rs1 << std::min(sshamt, 16);
if (shx > UINT16_MAX) {
P.set_vxsat();
p_rd = 0xFFFF;
p_rd = (uint16_t)UINT16_MAX;
} else {
p_rd = (uint16_t)shx;
}

13
riscv/insns/psshl_dws.h

@ -1,16 +1,13 @@
require_rv32;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
P_RD_RS1_DW_LOOP(32, 32, {
if (sshamt < 0) {
if (sshamt <= -32)
p_rd = 0;
else
p_rd = (uint32_t)p_rs1 >> (-sshamt);
p_rd = (uint64_t)(uint32_t)p_rs1 >> std::min(-sshamt, 32);
} else {
uint64_t shx = (sshamt >= 32) ? ((uint64_t)(uint32_t)p_rs1 << 32) : ((uint64_t)(uint32_t)p_rs1 << sshamt);
if (shx > 0xFFFFFFFFULL) {
uint64_t shx = (uint64_t)(uint32_t)p_rs1 << std::min(sshamt, 32);
if (shx > UINT32_MAX) {
P.set_vxsat();
p_rd = 0xFFFFFFFF;
p_rd = UINT32_MAX;
} else {
p_rd = (uint32_t)shx;
}

13
riscv/insns/psshl_hs.h

@ -1,15 +1,12 @@
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
P_RD_RS1_LOOP(16, 16, {
if (sshamt < 0) {
if (sshamt <= -16)
p_rd = 0;
else
p_rd = (uint16_t)p_rs1 >> (-sshamt);
p_rd = (uint32_t)(uint16_t)p_rs1 >> std::min(-sshamt, 16);
} else {
uint32_t shx = (sshamt >= 16) ? ((uint32_t)(uint16_t)p_rs1 << 16) : ((uint32_t)(uint16_t)p_rs1 << sshamt);
if (shx > 0xFFFF) {
uint32_t shx = (uint32_t)(uint16_t)p_rs1 << std::min(sshamt, 16);
if (shx > UINT16_MAX) {
P.set_vxsat();
p_rd = 0xFFFF;
p_rd = (uint16_t)UINT16_MAX;
} else {
p_rd = (uint16_t)shx;
}

13
riscv/insns/psshl_ws.h

@ -1,16 +1,13 @@
require_rv64;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
P_RD_RS1_LOOP(32, 32, {
if (sshamt < 0) {
if (sshamt <= -32)
p_rd = 0;
else
p_rd = (uint32_t)p_rs1 >> (-sshamt);
p_rd = (uint64_t)(uint32_t)p_rs1 >> std::min(-sshamt, 32);
} else {
uint64_t shx = (sshamt >= 32) ? ((uint64_t)(uint32_t)p_rs1 << 32) : ((uint64_t)(uint32_t)p_rs1 << sshamt);
if (shx > 0xFFFFFFFFULL) {
uint64_t shx = (uint64_t)(uint32_t)p_rs1 << std::min(sshamt, 32);
if (shx > UINT32_MAX) {
P.set_vxsat();
p_rd = 0xFFFFFFFF;
p_rd = UINT32_MAX;
} else {
p_rd = (uint32_t)shx;
}

16
riscv/insns/psshlr_dhs.h

@ -1,20 +1,14 @@
require_rv32;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
P_RD_RS1_DW_LOOP(16, 16, {
if (sshamt < 0) {
uint32_t shx;
if (sshamt < -16)
shx = 0;
else if (sshamt == -16)
shx = ((uint16_t)p_rs1 >> 15) & 1;
else
shx = ((uint32_t)(uint16_t)p_rs1 << 1) >> (-sshamt);
uint32_t shx = ((uint32_t)(uint16_t)p_rs1 << 1) >> std::min(-sshamt, 16);
p_rd = (uint16_t)((shx + 1) >> 1);
} else {
uint32_t shx = (sshamt >= 16) ? ((uint32_t)(uint16_t)p_rs1 << 16) : ((uint32_t)(uint16_t)p_rs1 << sshamt);
if (shx > 0xFFFF) {
uint32_t shx = (uint32_t)(uint16_t)p_rs1 << std::min(sshamt, 16);
if (shx > UINT16_MAX) {
P.set_vxsat();
p_rd = 0xFFFF;
p_rd = (uint16_t)UINT16_MAX;
} else {
p_rd = (uint16_t)shx;
}

16
riscv/insns/psshlr_dws.h

@ -1,20 +1,14 @@
require_rv32;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
P_RD_RS1_DW_LOOP(32, 32, {
if (sshamt < 0) {
uint64_t shx;
if (sshamt < -32)
shx = 0;
else if (sshamt == -32)
shx = ((uint32_t)p_rs1 >> 31) & 1;
else
shx = ((uint64_t)(uint32_t)p_rs1 << 1) >> (-sshamt);
uint64_t shx = ((uint64_t)(uint32_t)p_rs1 << 1) >> std::min(-sshamt, 32);
p_rd = (uint32_t)((shx + 1) >> 1);
} else {
uint64_t shx = (sshamt >= 32) ? ((uint64_t)(uint32_t)p_rs1 << 32) : ((uint64_t)(uint32_t)p_rs1 << sshamt);
if (shx > 0xFFFFFFFFULL) {
uint64_t shx = (uint64_t)(uint32_t)p_rs1 << std::min(sshamt, 32);
if (shx > UINT32_MAX) {
P.set_vxsat();
p_rd = 0xFFFFFFFF;
p_rd = UINT32_MAX;
} else {
p_rd = (uint32_t)shx;
}

16
riscv/insns/psshlr_hs.h

@ -1,19 +1,13 @@
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
P_RD_RS1_LOOP(16, 16, {
if (sshamt < 0) {
uint32_t shx;
if (sshamt < -16)
shx = 0;
else if (sshamt == -16)
shx = ((uint16_t)p_rs1 >> 15) & 1;
else
shx = ((uint32_t)(uint16_t)p_rs1 << 1) >> (-sshamt);
uint32_t shx = ((uint32_t)(uint16_t)p_rs1 << 1) >> std::min(-sshamt, 16);
p_rd = (uint16_t)((shx + 1) >> 1);
} else {
uint32_t shx = (sshamt >= 16) ? ((uint32_t)(uint16_t)p_rs1 << 16) : ((uint32_t)(uint16_t)p_rs1 << sshamt);
if (shx > 0xFFFF) {
uint32_t shx = (uint32_t)(uint16_t)p_rs1 << std::min(sshamt, 16);
if (shx > UINT16_MAX) {
P.set_vxsat();
p_rd = 0xFFFF;
p_rd = (uint16_t)UINT16_MAX;
} else {
p_rd = (uint16_t)shx;
}

16
riscv/insns/psshlr_ws.h

@ -1,20 +1,14 @@
require_rv64;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
P_RD_RS1_LOOP(32, 32, {
if (sshamt < 0) {
uint64_t shx;
if (sshamt < -32)
shx = 0;
else if (sshamt == -32)
shx = ((uint32_t)p_rs1 >> 31) & 1;
else
shx = ((uint64_t)(uint32_t)p_rs1 << 1) >> (-sshamt);
uint64_t shx = ((uint64_t)(uint32_t)p_rs1 << 1) >> std::min(-sshamt, 32);
p_rd = (uint32_t)((shx + 1) >> 1);
} else {
uint64_t shx = (sshamt >= 32) ? ((uint64_t)(uint32_t)p_rs1 << 32) : ((uint64_t)(uint32_t)p_rs1 << sshamt);
if (shx > 0xFFFFFFFFULL) {
uint64_t shx = (uint64_t)(uint32_t)p_rs1 << std::min(sshamt, 32);
if (shx > UINT32_MAX) {
P.set_vxsat();
p_rd = 0xFFFFFFFF;
p_rd = UINT32_MAX;
} else {
p_rd = (uint32_t)shx;
}

13
riscv/insns/shl.h

@ -1,15 +1,10 @@
require_extension('P');
require_rv64;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
uint128_t shx = RS1;
if (sshamt < 0) {
if (sshamt <= -64)
WRITE_RD(0);
else
WRITE_RD(RS1 >> (-sshamt));
WRITE_RD(shx >> std::min(-sshamt, 64));
} else {
if (sshamt >= 64)
WRITE_RD(0);
else
WRITE_RD(RS1 << sshamt);
WRITE_RD(shx << std::min(sshamt, 64));
}

15
riscv/insns/shlr.h

@ -1,19 +1,10 @@
require_extension('P');
require_rv64;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
if (sshamt < 0) {
__uint128_t shx;
if (sshamt < -64)
shx = 0;
else if (sshamt == -64)
shx = (RS1 >> 63) & 1;
else
shx = ((__uint128_t)RS1 << 1) >> (-sshamt);
uint128_t shx = ((uint128_t)RS1 << 1) >> std::min(-sshamt, 64);
WRITE_RD((uint64_t)((shx + 1) >> 1));
} else {
if (sshamt >= 64)
WRITE_RD(0);
else
WRITE_RD(RS1 << sshamt);
WRITE_RD((uint128_t)RS1 << std::min(sshamt, 64));
}

19
riscv/insns/sshar.h

@ -1,13 +1,16 @@
require_extension('P');
require_rv32;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
if (RS1 == 0)
WRITE_RD(0);
else if (sshamt >= 32) {
WRITE_RD((RS1 & 0x80000000) ? 0x80000000 : 0x7fffffff);
sreg_t val;
if (RS1 == 0) {
val = 0;
} else if (sshamt >= 32) {
val = (RS1 & 0x80000000) ? 0x80000000 : 0x7fffffff;
P.set_vxsat();
} else if (sshamt <= -32) {
val = 0;
} else {
val = sshamt >= 0 ? P_SAT(32, static_cast<sreg_t> (RS1) << sshamt) : ((RS1 >> -sshamt) + ((RS1 >> (-sshamt - 1)) & 1));
}
else if (sshamt <= -32)
WRITE_RD(0);
else
WRITE_RD(sshamt >= 0 ? P_SAT(32, static_cast<sreg_t> (RS1) << sshamt) : ((RS1 >> -sshamt) + ((RS1 >> (-sshamt - 1)) & 1)));
WRITE_RD(sext32(val));

17
riscv/insns/sshl.h

@ -1,18 +1,15 @@
require_extension('P');
require_rv32;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
uint64_t shx;
if (sshamt < 0) {
if (sshamt <= -32)
WRITE_RD(0);
else
WRITE_RD(RS1 >> (-sshamt));
shx = ((uint64_t)(uint32_t)RS1) >> std::min(-sshamt, 32);
} else {
uint64_t shx = (sshamt >= 32) ? ((uint64_t)RS1 << 32) : ((uint64_t)RS1 << sshamt);
if (shx > 0xFFFFFFFFULL) {
shx = (uint64_t)RS1 << std::min(sshamt, 32);
if (shx > UINT32_MAX) {
P.set_vxsat();
WRITE_RD(0xFFFFFFFF);
} else {
WRITE_RD((uint32_t)shx);
shx = UINT32_MAX;
}
}
WRITE_RD(sext32(shx));

22
riscv/insns/sshlr.h

@ -1,22 +1,16 @@
require_extension('P');
require_rv32;
sreg_t sshamt = P_FIELD(RS2, 0, 8);
int sshamt = P_FIELD(RS2, 0, 8);
uint64_t shx;
if (sshamt < 0) {
uint64_t shx;
if (sshamt < -32)
shx = 0;
else if (sshamt == -32)
shx = (RS1 >> 31) & 1;
else
shx = ((uint64_t)RS1 << 1) >> (-sshamt);
WRITE_RD((uint32_t)((shx + 1) >> 1));
shx = ((uint64_t)(uint32_t)RS1 << 1) >> std::min(-sshamt, 32);
shx = (shx + 1) >> 1;
} else {
uint64_t shx = (sshamt >= 32) ? ((uint64_t)RS1 << 32) : ((uint64_t)RS1 << sshamt);
if (shx > 0xFFFFFFFFULL) {
shx = (uint64_t)RS1 << std::min(sshamt, 32);
if (shx > UINT32_MAX) {
P.set_vxsat();
WRITE_RD(0xFFFFFFFF);
} else {
WRITE_RD((uint32_t)shx);
shx = UINT32_MAX;
}
}
WRITE_RD(sext32(shx));

Loading…
Cancel
Save