Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RV64G到RV32G的指令替换 #39

Open
shining1984 opened this issue Mar 26, 2021 · 13 comments
Open

RV64G到RV32G的指令替换 #39

shining1984 opened this issue Mar 26, 2021 · 13 comments

Comments

@shining1984
Copy link

目前已经改了一部分RV64G的指令,对应到RV32G的指令。本issue会将已经使用的转换列出来,为后续调试做参考。

@shining1984
Copy link
Author

shining1984 commented Mar 26, 2021

addw->add
addiw->addi
subw->sub
mulw->mul
andrw->andr
orrw->orr
xorrw->xorr
sllw->sll
sraw->sra
srlw->srl
negw->neg
ld->flw
sd->fsw
lwu->lw

remw->rem

@shining1984
Copy link
Author

在bishengJDK方面,marcoAssembler_riscv64.hpp中spill()和unspill()函数中,有ld->lw,ld->lwu,sd->sw,fsd->fsw,这种对应关系。这个对64位指令到32位指令的转换有参考意义。

@shining1984
Copy link
Author

shining1984 commented Apr 12, 2021

P24 32位 LW,LH,LHU,LB,LBU SW,SH,SB
image

64位 LD, LWU SD
image

P67 F FLW, FSW
image

D FLD,FSD
image

@shining1984
Copy link
Author

load 和 store 从64位到32位转换的规则更新:

LD->LW
LWU->LW
SD->SW

其余的指令都是可以32位和64位通用的。LW,LH,LHU,LB,LBU,SW,SH,SB ,FLW,FSW,FLD,FSD。
但是,仍然要区分,在从64位到32位的变换过程中,有没有从double变成float的需求。这决定着是否要从FLD、FSD转换为FLW、FSW。

@shining1984
Copy link
Author

addw->add
subw->sub
mulw->mul
divw->div
addiw->addi

@DingliZhang
Copy link

srliw -> srli
slliw -> slli
sraiw -> srai

@DingliZhang
Copy link

DingliZhang commented Oct 19, 2021

lr_d -> lr_w
sc_d-> sc_w
相关的issue:#197 #202

@shining1984
Copy link
Author

shining1984 commented Oct 20, 2021

srliw -> srli slliw -> slli sraiw -> srai

结合前面的工作,该系列进行整理后:

sllw->sll
slliw -> slli
sraw->sra
sraiw -> srai
srlw->srl
srliw -> srli

相关issue:#205

@shining1984
Copy link
Author

shining1984 commented Oct 20, 2021

加减乘除部分更新和总结修改规则如下:

addw->add
addiw->addi
subw->sub
mulw->mul
divw->div
divuw->divu

mul,mulh,mulhsu是32/64通用指令,不用修改。

相关issue: #208

@shining1984
Copy link
Author

shining1984 commented Oct 20, 2021

load/store系列转换规则:

load 和 store 从64位到32位转换的规则更新:

ld->lw
lwu->lw
sd->sw

lb,lbu,lh,lhu,lla,lui,lw
sb,sh,sw
fld,flw,fsd,fsw
lr.w, sc.w
这些都是RV32/64通用的指令。

lr.d通常表示为lr_d,需要更新为lr.w(lr_w)。
sc.d通常表示为sc_d,需要更新为sc.w(lc_w)。

la,li为伪指令,二者本身是不区分RV32/64的,但是不同的位数(RV32或RV64)在宏汇编器中的实现不同,这个需注意。

相关issue:#197 #202 #213

@DingliZhang
Copy link

DingliZhang commented Oct 21, 2021

在调试过程中于l2f所对应的汇编码中发现了非法指令 0xd0250553

l2f  137 l2f  [0x3cce8cc0, 0x3cce8d00]  64 bytes

BFD: unrecognized disassembler option: 
  0x3cce8cc0: lw	a0,0(s4)
  0x3cce8cc4: addi	s4,s4,8
  0x3cce8cc8: 0xd0250553

对应rv64 only的 fcvt.s.l,找到对应的源码位置位于 templateTable_riscv32.cpp

case Bytecodes::_l2f:
    __ fcvt_s_w(f10, x10);
    break;

需要修改D/F相关的几个指令:

fcvt.l.s 通常表示为 fcvt_l_s,需要更新为 fcvt.w.s(fcvt_w_s),
fcvt.lu.s 通常表示为 fcvt_lu_s,需要更新为 fcvt.wu.s(fcvt_wu_s),
fcvt.s.l 通常表示为 fcvt_s_l,需要更新为 fcvt.s.w(fcvt_s_w),
fcvt.s.lu 通常表示为 fcvt_s_lu,需要更新为 fcvt.s.wu(fcvt_s_wu),
fcvt.l.d 通常表示为 fcvt_l_d,需要更新为 fcvt.w.d(fcvt_w_d),
fcvt.lu.d 通常表示为 fcvt_lu_d,需要更新为 fcvt.wu.d(fcvt_wu_d),
fmv.x.d 通常表示为 fmv_x_d,需要更新为 fcvt.x.w(fcvt_x_w),
fcvt.d.l 通常表示为 fcvt_d_l,需要更新为 fcvt.d.w(fcvt_d_w),
fcvt.d.lu 通常表示为 fcvt_d_lu,需要更新为 fcvt.d.wu(fcvt_d_wu),
fmv.d.x 通常表示为 fmv_d_x,需要更新为 fcvt.w.x(fcvt_w_x)。

已提交 #212 ,对当前运行结果没有影响,请 @shining1984 @zhangxiang-plct review

补充:
RV32D中:
fld, fsd
fadd.d, fsub.d, fmul.d, fdiv.d, fsqrt.d, fsgnj.d, fsgnjn.d, fsgnjx.d, fmin.d, fmax.d
feq.d, flt.d, fle.d, fclass.d
fcvt.s.d, fcvt.d.s, fcvt.w.d, fcvt.wu.d, fcvt.d.w, fcvt.d.wu, fmv.d.w

RV32F中:
flw, fsw
fadd.s, fsub.s, fmul.s, fdiv.s, fsqrt.s, fsgnj.s, fsgnjn.s, fsgnjx.s, fmin.s, fmax.s
feq.s, flt.s, fle.s, fclass.s
fcvt.w.s,fcvt.wu.s, fcvt.s.w,fcvt.s.wu, fmv.w.x, fmv.x.w
为RV32/64通用的指令。


20220112更新

long与double/float转换的字节码中直接替换 fcvt_s_l/fcvt_d_l/fcvt_l_s_safe/fcvt_l_d_safefcvt_s_w/fcvt_d_w/fcvt_w_s_safe/fcvt_w_d_safe 是有问题的,会导致数据丢失,分析与修复详见 #326

因为java中Long类型数据(64bit)与Double/Float数据的转换逻辑,而rv32中原生的指令都是32bit的整型与浮点型的转换,在rv32中double为64位,long为32位,所以直接使用 fcvt_s_w/fcvt_d_w/fcvt_w_s_safe/fcvt_w_d_safe 进行转换会导致数据丢失的问题。

所以 #326 采用了类似软浮点的操作,使用 SharedRuntime 将转换操作用c++函数来实现。

@shining1984
Copy link
Author

RISC-V原子操作(A扩展)的指令有两类:存取系列指令和原子内存操作指令(AMO)。

其中,存取系列指令在前面介绍过,lr.d/lr.w, sc.d/sc.w.其中lr.d和sc.d是64位的。lr.w和sc.w是64/32都可以的。
lr.d通常表示为lr_d,需要更新为lr.w(lr_w)。
sc.d通常表示为sc_d,需要更新为sc.w(lc_w)。

AMO指令有:
64位 amoadd.d amoand.d amomax.d amomaxu.d amomin.d amominu.d amoor.d amoswap.d amoxor.d
64位/32位 amoadd.w amoand.w amomax.w amomaxu.w amomin.w amominu.w amoor.w amoswap.w amoxor.w

原子指令的转换规则为将64位的“.d”结尾的指令替换为64位/32位皆可的".w"结尾的指令。

相关issue: #210

@shining1984
Copy link
Author

对关系比较指令进行梳理:

64/32通用指令:

beq beqz bge begu begz bgt bgtu bgtz ble bleu blez blt bltz bltu bne bnez seqz sgtz slt slti sltiu sltu sltz snez

没有发现需要进行转换的指令,目前该部分指令都是64位和32位通用的。

相关issue: #222

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants