mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj/riscv: factor out shift constant code
Move the code that tests to see if a constant can be represented by a 32 bit signed integer and a logical left shift. This reduces duplication and increases readability. Also add test coverage now that this is an independent function. Change-Id: Id25395b1380b00cf5b69ca201b7715ef84f7ade6 Reviewed-on: https://go-review.googlesource.com/c/go/+/652777 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Meng Zhuo <mengzhuo1203@gmail.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
574e836055
commit
af133d86e4
2 changed files with 86 additions and 8 deletions
|
|
@ -135,10 +135,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
|
||||
case AMOV:
|
||||
if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == obj.REG_NONE && int64(int32(p.From.Offset)) != p.From.Offset {
|
||||
ctz := bits.TrailingZeros64(uint64(p.From.Offset))
|
||||
val := p.From.Offset >> ctz
|
||||
if int64(int32(val)) == val {
|
||||
// It's ok. We can handle constants with many trailing zeros.
|
||||
if isShiftConst(p.From.Offset) {
|
||||
break
|
||||
}
|
||||
// Put >32-bit constants in memory and load them.
|
||||
|
|
@ -2223,6 +2220,24 @@ func encodingForAs(as obj.As) (*encoding, error) {
|
|||
return &insData.enc, nil
|
||||
}
|
||||
|
||||
// splitShiftConst attempts to split a constant into a signed 32 bit integer
|
||||
// and a corresponding left shift.
|
||||
func splitShiftConst(v int64) (imm int64, lsh int, ok bool) {
|
||||
lsh = bits.TrailingZeros64(uint64(v))
|
||||
c := v >> lsh
|
||||
if int64(int32(c)) != c {
|
||||
return 0, 0, false
|
||||
}
|
||||
return c, lsh, true
|
||||
}
|
||||
|
||||
// isShiftConst indicates whether a constant can be represented as a signed
|
||||
// 32 bit integer that is left shifted.
|
||||
func isShiftConst(v int64) bool {
|
||||
_, lsh, ok := splitShiftConst(v)
|
||||
return ok && lsh > 0
|
||||
}
|
||||
|
||||
type instruction struct {
|
||||
p *obj.Prog // Prog that instruction is for
|
||||
as obj.As // Assembler opcode
|
||||
|
|
@ -2504,10 +2519,9 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
|
|||
// SLLI $63, X10, X10
|
||||
var insSLLI *instruction
|
||||
if err := immIFits(ins.imm, 32); err != nil {
|
||||
ctz := bits.TrailingZeros64(uint64(ins.imm))
|
||||
if err := immIFits(ins.imm>>ctz, 32); err == nil {
|
||||
ins.imm = ins.imm >> ctz
|
||||
insSLLI = &instruction{as: ASLLI, rd: ins.rd, rs1: ins.rd, imm: int64(ctz)}
|
||||
if c, lsh, ok := splitShiftConst(ins.imm); ok {
|
||||
ins.imm = c
|
||||
insSLLI = &instruction{as: ASLLI, rd: ins.rd, rs1: ins.rd, imm: int64(lsh)}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue