diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-09-13 21:51:21 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-13 15:51:21 +0200 |
| commit | 28dcd34624afb9bd14d838d5c1ae6123c8dc49fd (patch) | |
| tree | e7282c547d5e430ff283929b03de208c28dbb0e7 | |
| parent | 13b7398b3af0ba3735188565a03aaaddf6409763 (diff) | |
| download | box64-28dcd34624afb9bd14d838d5c1ae6123c8dc49fd.tar.gz box64-28dcd34624afb9bd14d838d5c1ae6123c8dc49fd.zip | |
[RV64_DYNAREC] Added some support for XTheadBb extension (#977)
* [RV64_DYNAREC] Added XTheadBb instructions * SRRIxw * GETGB
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_shift.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 58 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_emitter.h | 63 |
3 files changed, 103 insertions, 22 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c index 7030c674..80dea7a9 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c @@ -421,6 +421,8 @@ void emit_rol32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, } if(rv64_zbb) { RORIxw(s1, s1, (rex.w?64:32)-c); + } else if (rv64_xtheadbb) { + TH_SRRIxw(s1, s1, (rex.w?64:32)-c); } else { SLLIxw(s3, s1, c); SRLIxw(s1, s1, (rex.w?64:32)-c); @@ -466,6 +468,8 @@ void emit_ror32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, } if(rv64_zbb) { RORIxw(s1, s1, c); + } else if (rv64_xtheadbb) { + TH_SRRIxw(s1, s1, c); } else { SRLIxw(s3, s1, c); SLLIxw(s1, s1, (rex.w?64:32)-c); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 51d7817f..04a20308 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -210,7 +210,15 @@ wb2 = (wback>>2)*8; \ wback = xRAX+(wback&3); \ } \ - if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);} \ + if (wb2) { \ + if (rv64_xtheadbb) { \ + TH_EXTU(i, wback, 15, 8); \ + } else { \ + MV(i, wback); \ + SRLI(i, i, wb2); \ + ANDI(i, i, 0xff); \ + } \ + } else ANDI(i, wback, 0xff);\ wb1 = 0; \ ed = i; \ } else { \ @@ -230,7 +238,15 @@ wb2 = (wback>>2)*8; \ wback = xRAX+(wback&3); \ } \ - if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);} \ + if (wb2) { \ + if (rv64_xtheadbb) { \ + TH_EXTU(i, wback, 15, 8); \ + } else { \ + MV(i, wback); \ + SRLI(i, i, wb2); \ + ANDI(i, i, 0xff); \ + } \ + } else ANDI(i, wback, 0xff);\ wb1 = 0; \ ed = i; \ } else { \ @@ -274,7 +290,15 @@ wb2 = (wback>>2)*8; \ wback = xRAX+(wback&3); \ } \ - if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);} \ + if (wb2) { \ + if (rv64_xtheadbb) { \ + TH_EXTU(i, wback, 15, 8); \ + } else { \ + MV(i, wback); \ + SRLI(i, i, wb2); \ + ANDI(i, i, 0xff); \ + } \ + } else ANDI(i, wback, 0xff);\ wb1 = 0; \ ed = i; \ } else { \ @@ -286,16 +310,24 @@ } //GETGB will use i for gd -#define GETGB(i) if(rex.rex) { \ - gb1 = xRAX+((nextop&0x38)>>3)+(rex.r<<3); \ - gb2 = 0; \ - } else { \ - gd = (nextop&0x38)>>3; \ - gb2 = ((gd&4)>>2); \ - gb1 = xRAX+(gd&3); \ - } \ - gd = i; \ - if (gb2) {MV(gd, gb1); SRLI(gd, gd, 8); ANDI(gd, gd, 0xff);} else {ANDI(gd, gb1, 0xff);} +#define GETGB(i) if(rex.rex) { \ + gb1 = xRAX+((nextop&0x38)>>3)+(rex.r<<3); \ + gb2 = 0; \ + } else { \ + gd = (nextop&0x38)>>3; \ + gb2 = ((gd&4)>>2); \ + gb1 = xRAX+(gd&3); \ + } \ + gd = i; \ + if (gb2) { \ + if (rv64_xtheadbb) { \ + TH_EXTU(gd, gb1, 15, 8);\ + } else { \ + MV(gd, gb1); \ + SRLI(gd, gd, 8); \ + ANDI(gd, gd, 0xff); \ + } \ + } else ANDI(gd, gb1, 0xff); // Write gb (gd) back to original register / memory, using s1 as scratch #define GBBACK(s1) if(gb2) { \ diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index 4eebb353..1caebc90 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -673,19 +673,64 @@ f28–31 ft8–11 FP temporaries Caller // XTheadBb - Basic bit-manipulation +#define TH_SRRIxw(rd, rs1, imm) if(rex.w) { \ + TH_SRRI(rd, rs1, imm); \ + } else { \ + TH_SRRIW(rd, rs1, imm); \ + } + // Perform a cyclic right shift. // reg[rd] := (reg[rs1] >> imm6) | (reg[rs1] << (xlen - imm6)) #define TH_SRRI(rd, rs1, imm6) EMIT(I_type(0b000100000000|(imm6&0x3f), rs1, 0b001, rd, 0b0001011)) -// TODO -// th.srriw rd, rs1, imm5 Cyclic right shift on word operand -// th.ext rd, rs1, imm1, imm2 Extract and sign-extend bits -// th.extu rd, rs1, imm1, imm2 Extract and zero-extend bits -// th.ff0 rd, rs1 Find first '0'-bit -// th.ff1 rd, rs1 Find first '1'-bit -// th.rev rd, rs1 Reverse byte order -// th.revw rd, rs1 Reverse byte order of word operand -// th.tstnbz rd, rs1 Test for NUL bytes +// Perform a cyclic right shift on word operand. +// data := zext.w(reg[rs1]) +// reg[rd] := (data >> imm5) | (data << (32 - imm5)) +#define TH_SRRIW(rd, rs1, imm5) EMIT(I_type(0b000101000000|(imm5&0x1f), rs1, 0b001, rd, 0b0001011)) + +// Extract and sign-extend bits. +// reg[rd] := sign_extend(reg[rs1][imm1:imm2]) +#define TH_EXT(rd, rs1, imm1, imm2) EMIT(I_type(((imm1&0x1f)<<6)|(imm2&0x1f), rs1, 0b010, rd, 0b0001011)) + +// Extract and zero-extend bits. +// reg[rd] := zero_extend(reg[rs1][imm1:imm2]) +#define TH_EXTU(rd, rs1, imm1, imm2) EMIT(I_type(((imm1&0x1f)<<6)|(imm2&0x1f), rs1, 0b011, rd, 0b0001011)) + +// Find first '0'-bit +// for i=xlen..0: +// if reg[rs1][i] == 0: +// break; +// reg[rd] = (xlen - 1) - i +#define TH_FF0(rd, rs1) EMIT(I_type(0b100001000000, rs1, 0b001, rd, 0b0001011)) + +// Find first '1'-bit +// for i=xlen..0: +// if reg[rs1][i] == 1: +// break; +// reg[rd] = (xlen - 1) - i +#define TH_FF1(rd, rs1) EMIT(I_type(0b100001100000, rs1, 0b001, rd, 0b0001011)) + +// Reverse the byte order. +// for i=0..(xlen/8-1): +// j := xlen/8 - 1 - i +// tmp[i] := reg[rs1][j] +// reg[rd] := tmp +#define TH_REV(rd, rs1) EMIT(I_type(0b100000100000, rs1, 0b001, rd, 0b0001011)) + +// Reverse the byte order of a word operand. +// for i=0..3: +// j := 3 - i +// tmp[i] := reg[rs1][j] +// reg[rd] := tmp +#define TH_REVW(rd, rs1) EMIT(I_type(0b100100000000, rs1, 0b001, rd, 0b0001011)) + +// Test for NUL bytes. +// for i=0..(xlen/8-1): +// if reg[rs1][i] == 0: +// reg[rd][i] := 0xff +// else +// reg[rd][i] := 0 +#define TH_TSTNBZ(rd, rs1) EMIT(I_type(0b1000000000000, rs1, 0b001, rd, 0b0001011)) // XTheadBs - Single-bit instructions |