Skip to content

Commit 8cf5293

Browse files
committed
cmd/internal/obj/riscv: split immediates larger than 12-bits
Handle immediates larger than 12-bits by rewriting as an LUI instruction with the high bits, followed by the original instruction with the low bits. Based on the riscv-go port. Updates #27532 Change-Id: I8ed6d6e6db06fb8a27f3ab75f467ec2b7ff1f075 Reviewed-on: https://go-review.googlesource.com/c/go/+/204626 Reviewed-by: Cherry Zhang <[email protected]> Run-TryBot: Cherry Zhang <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 1046a9c commit 8cf5293

File tree

1 file changed

+110
-0
lines changed
  • src/cmd/internal/obj/riscv

1 file changed

+110
-0
lines changed

src/cmd/internal/obj/riscv/obj.go

+110
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,116 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
486486
}
487487
}
488488

489+
// Split immediates larger than 12-bits.
490+
for p := cursym.Func.Text; p != nil; p = p.Link {
491+
switch p.As {
492+
// <opi> $imm, REG, TO
493+
case AADDI, AANDI, AORI, AXORI:
494+
// LUI $high, TMP
495+
// ADDI $low, TMP, TMP
496+
// <op> TMP, REG, TO
497+
q := *p
498+
low, high, err := Split32BitImmediate(p.From.Offset)
499+
if err != nil {
500+
ctxt.Diag("%v: constant %d too large", p, p.From.Offset, err)
501+
}
502+
if high == 0 {
503+
break // no need to split
504+
}
505+
506+
p.As = ALUI
507+
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: high}
508+
p.Reg = 0
509+
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
510+
p.Spadj = 0 // needed if TO is SP
511+
p = obj.Appendp(p, newprog)
512+
513+
p.As = AADDIW
514+
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: low}
515+
p.Reg = REG_TMP
516+
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
517+
p = obj.Appendp(p, newprog)
518+
519+
switch q.As {
520+
case AADDI:
521+
p.As = AADD
522+
case AANDI:
523+
p.As = AAND
524+
case AORI:
525+
p.As = AOR
526+
case AXORI:
527+
p.As = AXOR
528+
default:
529+
ctxt.Diag("progedit: unsupported inst %v for splitting", q)
530+
}
531+
p.Spadj = q.Spadj
532+
p.To = q.To
533+
p.Reg = q.Reg
534+
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
535+
536+
// <load> $imm, REG, TO (load $imm+(REG), TO)
537+
// <store> $imm, REG, TO (store $imm+(TO), REG)
538+
case ALD, ALB, ALH, ALW, ALBU, ALHU, ALWU,
539+
ASD, ASB, ASH, ASW:
540+
// LUI $high, TMP
541+
// ADDI $low, TMP, TMP
542+
q := *p
543+
low, high, err := Split32BitImmediate(p.From.Offset)
544+
if err != nil {
545+
ctxt.Diag("%v: constant %d too large", p, p.From.Offset)
546+
}
547+
if high == 0 {
548+
break // no need to split
549+
}
550+
551+
switch q.As {
552+
case ALD, ALB, ALH, ALW, ALBU, ALHU, ALWU:
553+
// LUI $high, TMP
554+
// ADD TMP, REG, TMP
555+
// <load> $low, TMP, TO
556+
p.As = ALUI
557+
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: high}
558+
p.Reg = 0
559+
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
560+
p.Spadj = 0 // needed if TO is SP
561+
p = obj.Appendp(p, newprog)
562+
563+
p.As = AADD
564+
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
565+
p.Reg = q.Reg
566+
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
567+
p = obj.Appendp(p, newprog)
568+
569+
p.As = q.As
570+
p.To = q.To
571+
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: low}
572+
p.Reg = REG_TMP
573+
574+
case ASD, ASB, ASH, ASW:
575+
// LUI $high, TMP
576+
// ADD TMP, TO, TMP
577+
// <store> $low, REG, TMP
578+
p.As = ALUI
579+
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: high}
580+
p.Reg = 0
581+
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
582+
p.Spadj = 0 // needed if TO is SP
583+
p = obj.Appendp(p, newprog)
584+
585+
p.As = AADD
586+
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
587+
p.Reg = q.To.Reg
588+
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
589+
p = obj.Appendp(p, newprog)
590+
591+
p.As = q.As
592+
p.Reg = q.Reg
593+
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
594+
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: low}
595+
}
596+
}
597+
}
598+
489599
setPCs(cursym.Func.Text, 0)
490600

491601
// Resolve branch and jump targets.

0 commit comments

Comments
 (0)