diff options
| author | Xiaolin Zhao <zhaoxiaolin@loongson.cn> | 2025-09-24 17:21:40 +0800 |
|---|---|---|
| committer | abner chenc <chenguoqi@loongson.cn> | 2025-10-27 18:21:57 -0700 |
| commit | 916e682d5167faad1bb961ec28cac74f05f145f7 (patch) | |
| tree | 692bd58aadbb0445048aff2838d942c868588a45 /src/cmd/internal | |
| parent | 2835b994fb8c7125180d912a457308d64a30542f (diff) | |
| download | go-916e682d5167faad1bb961ec28cac74f05f145f7.tar.xz | |
cmd/internal/obj, cmd/asm: reclassify the offset of memory access operations on loong64
This CL also fixes the encoding error of LL/SC[V] instruction and
adds the handling of offset greater than 16 bits in MOV{W/V}P instructions.
Change-Id: I7a8fab4b68a6839da81c5e59af1f42289d00ef61
Reviewed-on: https://go-review.googlesource.com/c/go/+/706435
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Meidan Li <limeidan@loongson.cn>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/cmd/internal')
| -rw-r--r-- | src/cmd/internal/obj/loong64/a.out.go | 22 | ||||
| -rw-r--r-- | src/cmd/internal/obj/loong64/asm.go | 206 |
2 files changed, 154 insertions, 74 deletions
diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go index 3cdbeb12a3..3a676db922 100644 --- a/src/cmd/internal/obj/loong64/a.out.go +++ b/src/cmd/internal/obj/loong64/a.out.go @@ -249,7 +249,13 @@ func init() { } const ( - BIG = 2046 + BIG_8 = 128 - 2 // FIXME (not sure if -2 is appropriate) + BIG_9 = 256 - 2 + BIG_10 = 512 - 2 + BIG_11 = 1024 - 2 + BIG_12 = 2046 + BIG_16 = 32768 - 2 + BIG_32 = 2147483648 - 2 ) const ( @@ -397,10 +403,16 @@ const ( C_BRAN C_SAUTO C_LAUTO - C_ZOREG - C_SOREG - C_LOREG - C_ROFF // register offset + C_ZOREG // An $0+reg memory op + C_SOREG_8 // An $n+reg memory arg where n is a 8 bit signed offset + C_SOREG_9 // An $n+reg memory arg where n is a 9 bit signed offset + C_SOREG_10 // An $n+reg memory arg where n is a 10 bit signed offset + C_SOREG_11 // An $n+reg memory arg where n is a 11 bit signed offset + C_SOREG_12 // An $n+reg memory arg where n is a 12 bit signed offset + C_SOREG_16 // An $n+reg memory arg where n is a 16 bit signed offset + C_LOREG_32 // An $n+reg memory arg where n is a 32 bit signed offset + C_LOREG_64 // An $n+reg memory arg where n is a 64 bit signed offset + C_ROFF // register offset C_ADDR C_TLS_LE C_TLS_IE diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go index 5a61acac87..7eb5668d82 100644 --- a/src/cmd/internal/obj/loong64/asm.go +++ b/src/cmd/internal/obj/loong64/asm.go @@ -162,46 +162,41 @@ var optab = []Optab{ {AMOVV, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0}, {AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0}, {AMOVBU, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0}, - {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AMOVWU, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AMOVV, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AVMOVQ, C_VREG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, + {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AMOVWU, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AMOVV, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AVMOVQ, C_VREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, {AVMOVQ, C_VREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGZERO, 0}, {AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGZERO, 0}, - {ASC, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {ASCV, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, {AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, {AMOVWU, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, {AMOVV, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, {AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, {AMOVBU, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, - {AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AMOVWU, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AMOVV, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AVMOVQ, C_SOREG, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0}, - {AXVMOVQ, C_SOREG, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVW, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVWU, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVV, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVB, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVBU, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0}, + {AXVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0}, {AVMOVQ, C_SAUTO, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0}, {AXVMOVQ, C_SAUTO, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0}, - {ALL, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {ALLV, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, {AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, {AMOVWU, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, {AMOVV, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, {AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, {AMOVBU, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, - {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {AMOVWU, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {AMOVV, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {ASC, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, + {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, + {AMOVWU, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, + {AMOVV, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, + {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, + {AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, {AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, {AMOVWU, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, {AMOVV, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, @@ -212,19 +207,20 @@ var optab = []Optab{ {AMOVV, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0}, {AMOVB, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0}, {AMOVBU, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0}, - {AMOVWP, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 73, 4, 0, 0}, - {AMOVWP, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 73, 4, 0, 0}, + {AMOVWP, C_REG, C_NONE, C_NONE, C_SOREG_16, C_NONE, 73, 4, 0, 0}, + {AMOVWP, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 73, 12, 0, 0}, + {AMOVWP, C_REG, C_NONE, C_NONE, C_LOREG_64, C_NONE, 73, 24, 0, 0}, {AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, {AMOVWU, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, {AMOVV, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, {AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, {AMOVBU, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, - {AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, - {AMOVWU, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, - {AMOVV, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, - {AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, - {AMOVBU, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVW, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVWU, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVV, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVB, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVBU, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, {AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0}, {AMOVWU, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0}, {AMOVV, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0}, @@ -235,8 +231,9 @@ var optab = []Optab{ {AMOVV, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0}, {AMOVB, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0}, {AMOVBU, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0}, - {AMOVWP, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 74, 4, 0, 0}, - {AMOVWP, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 74, 4, 0, 0}, + {AMOVWP, C_SOREG_16, C_NONE, C_NONE, C_REG, C_NONE, 74, 4, 0, 0}, + {AMOVWP, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 74, 12, 0, 0}, + {AMOVWP, C_LOREG_64, C_NONE, C_NONE, C_REG, C_NONE, 74, 24, 0, 0}, {AMOVW, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0}, {AMOVV, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0}, @@ -333,25 +330,25 @@ var optab = []Optab{ {AMOVF, C_SAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGSP, 0}, {AMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGSP, 0}, - {AMOVF, C_SOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0}, - {AMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0}, + {AMOVF, C_SOREG_12, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0}, + {AMOVD, C_SOREG_12, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0}, {AMOVF, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGSP, 0}, {AMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGSP, 0}, - {AMOVF, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0}, - {AMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0}, + {AMOVF, C_LOREG_32, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0}, + {AMOVD, C_LOREG_32, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0}, {AMOVF, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 51, 8, 0, 0}, {AMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 51, 8, 0, 0}, {AMOVF, C_FREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 29, 4, REGSP, 0}, {AMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 29, 4, REGSP, 0}, - {AMOVF, C_FREG, C_NONE, C_NONE, C_SOREG, C_NONE, 29, 4, REGZERO, 0}, - {AMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, C_NONE, 29, 4, REGZERO, 0}, + {AMOVF, C_FREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 29, 4, REGZERO, 0}, + {AMOVD, C_FREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 29, 4, REGZERO, 0}, {AMOVF, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 29, 12, REGSP, 0}, {AMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 29, 12, REGSP, 0}, - {AMOVF, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 29, 12, REGZERO, 0}, - {AMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 29, 12, REGZERO, 0}, + {AMOVF, C_FREG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 29, 12, REGZERO, 0}, + {AMOVD, C_FREG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 29, 12, REGZERO, 0}, {AMOVF, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, {AMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, @@ -426,11 +423,11 @@ var optab = []Optab{ {AVMOVQ, C_ELEM, C_NONE, C_NONE, C_ARNG, C_NONE, 45, 4, 0, 0}, - {AVMOVQ, C_SOREG, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, - {AXVMOVQ, C_SOREG, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, + {AVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, + {AXVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, - {APRELD, C_SOREG, C_U5CON, C_NONE, C_NONE, C_NONE, 47, 4, 0, 0}, - {APRELDX, C_SOREG, C_DCON, C_U5CON, C_NONE, C_NONE, 48, 20, 0, 0}, + {APRELD, C_SOREG_12, C_U5CON, C_NONE, C_NONE, C_NONE, 47, 4, 0, 0}, + {APRELDX, C_SOREG_16, C_DCON, C_U5CON, C_NONE, C_NONE, 48, 20, 0, 0}, {AALSLV, C_U3CON, C_REG, C_REG, C_REG, C_NONE, 64, 4, 0, 0}, @@ -678,7 +675,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { bp := c.cursym.P var i int32 - var out [5]uint32 + var out [6]uint32 for p := c.cursym.Func().Text.Link; p != nil; p = p.Link { c.pc = p.Pc o = c.oplook(p) @@ -778,7 +775,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { a.Reg = obj.REG_NONE } c.instoffset = int64(c.autosize) + a.Offset - if c.instoffset >= -BIG && c.instoffset < BIG { + if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { return C_SAUTO } return C_LAUTO @@ -790,7 +787,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { a.Reg = obj.REG_NONE } c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize - if c.instoffset >= -BIG && c.instoffset < BIG { + if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { return C_SAUTO } return C_LAUTO @@ -808,10 +805,23 @@ func (c *ctxt0) aclass(a *obj.Addr) int { if c.instoffset == 0 { return C_ZOREG } - if c.instoffset >= -BIG && c.instoffset < BIG { - return C_SOREG + if c.instoffset >= -BIG_8 && c.instoffset < BIG_8 { + return C_SOREG_8 + } else if c.instoffset >= -BIG_9 && c.instoffset < BIG_9 { + return C_SOREG_9 + } else if c.instoffset >= -BIG_10 && c.instoffset < BIG_10 { + return C_SOREG_10 + } else if c.instoffset >= -BIG_11 && c.instoffset < BIG_11 { + return C_SOREG_11 + } else if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { + return C_SOREG_12 + } else if c.instoffset >= -BIG_16 && c.instoffset < BIG_16 { + return C_SOREG_16 + } else if c.instoffset >= -BIG_32 && c.instoffset < BIG_32 { + return C_LOREG_32 + } else { + return C_LOREG_64 } - return C_LOREG case obj.NAME_GOTREF: return C_GOTADDR @@ -828,7 +838,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { case obj.NAME_NONE: c.instoffset = a.Offset if a.Reg != 0 { - if -BIG <= c.instoffset && c.instoffset <= BIG { + if -BIG_12 <= c.instoffset && c.instoffset <= BIG_12 { return C_SACON } if isint32(c.instoffset) { @@ -857,7 +867,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { a.Reg = obj.REG_NONE } c.instoffset = int64(c.autosize) + a.Offset - if c.instoffset >= -BIG && c.instoffset < BIG { + if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { return C_SACON } return C_LACON @@ -869,7 +879,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { a.Reg = obj.REG_NONE } c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize - if c.instoffset >= -BIG && c.instoffset < BIG { + if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { return C_SACON } return C_LACON @@ -1271,10 +1281,33 @@ func cmp(a int, b int) bool { case C_REG: return b == C_ZCON - case C_LOREG: - return b == C_ZOREG || b == C_SOREG + case C_LOREG_64: + if b == C_ZOREG || b == C_SOREG_8 || + b == C_SOREG_9 || b == C_SOREG_10 || + b == C_SOREG_11 || b == C_SOREG_12 || + b == C_SOREG_16 || b == C_LOREG_32 { + return true + } + + case C_LOREG_32: + return cmp(C_SOREG_16, b) + + case C_SOREG_16: + return cmp(C_SOREG_12, b) + + case C_SOREG_12: + return cmp(C_SOREG_11, b) + + case C_SOREG_11: + return cmp(C_SOREG_10, b) + + case C_SOREG_10: + return cmp(C_SOREG_9, b) - case C_SOREG: + case C_SOREG_9: + return cmp(C_SOREG_8, b) + + case C_SOREG_8: return b == C_ZOREG } @@ -1453,6 +1486,10 @@ func buildop(ctxt *obj.Link) { case AMOVWP: opset(AMOVVP, r0) + opset(ASC, r0) + opset(ASCV, r0) + opset(ALL, r0) + opset(ALLV, r0) case AMUL: opset(AMULU, r0) @@ -1522,10 +1559,6 @@ func buildop(ctxt *obj.Link) { AMOVWU, AVMOVQ, AXVMOVQ, - ALL, - ALLV, - ASC, - ASCV, ANEGW, ANEGV, AWORD, @@ -2051,6 +2084,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { o3 := uint32(0) o4 := uint32(0) o5 := uint32(0) + o6 := uint32(0) add := AADDU add = AADDVU @@ -2955,18 +2989,51 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { o4 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) case 73: - v := c.regoff(&p.To) + v := c.vregoff(&p.To) + r := p.To.Reg if v&3 != 0 { c.ctxt.Diag("%v: offset must be a multiple of 4.\n", p) } - o1 = OP_14IRR(c.opirr(p.As), uint32(v>>2), uint32(p.To.Reg), uint32(p.From.Reg)) + + switch o.size { + case 4: // 16 bit + o1 = OP_14IRR(c.opirr(p.As), uint32(v>>2), uint32(r), uint32(p.From.Reg)) + case 12: // 32 bit + o1 = OP_16IRR(c.opirr(AADDV16), uint32(v>>16), uint32(REG_R0), uint32(REGTMP)) + o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP)) + o3 = OP_14IRR(c.opirr(p.As), uint32(v>>2), uint32(REGTMP), uint32(p.From.Reg)) + case 24: // 64 bit + o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP)) + o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) + o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) + o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) + o5 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(r)) + o6 = OP_14IRR(c.opirr(p.As), uint32(0), uint32(r), uint32(p.From.Reg)) + } case 74: - v := c.regoff(&p.From) + v := c.vregoff(&p.From) + r := p.From.Reg if v&3 != 0 { c.ctxt.Diag("%v: offset must be a multiple of 4.\n", p) } - o1 = OP_14IRR(c.opirr(-p.As), uint32(v>>2), uint32(p.From.Reg), uint32(p.To.Reg)) + + switch o.size { + case 4: // 16 bit + o1 = OP_14IRR(c.opirr(-p.As), uint32(v>>2), uint32(r), uint32(p.To.Reg)) + case 12: // 32 bit + o1 = OP_16IRR(c.opirr(AADDV16), uint32(v>>16), uint32(REG_R0), uint32(REGTMP)) + o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP)) + o3 = OP_14IRR(c.opirr(-p.As), uint32(v>>2), uint32(REGTMP), uint32(p.To.Reg)) + case 24: // 64 bit + o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP)) + o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) + o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) + o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) + o5 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(r)) + o6 = OP_14IRR(c.opirr(p.As), uint32(0), uint32(r), uint32(p.To.Reg)) + } + } out[0] = o1 @@ -2974,6 +3041,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { out[2] = o3 out[3] = o4 out[4] = o5 + out[5] = o6 } // checkoperand checks if operand >= 0 && operand <= maxoperand @@ -4143,13 +4211,13 @@ func (c *ctxt0) opirr(a obj.As) uint32 { case AROTRV: return 0x004d << 16 case -ALL: - return 0x020 << 24 + return 0x020 << 24 // ll.w case -ALLV: - return 0x022 << 24 + return 0x022 << 24 // ll.d case ASC: - return 0x021 << 24 + return 0x021 << 24 // sc.w case ASCV: - return 0x023 << 24 + return 0x023 << 24 // sc.d case AVANDB: return 0x1CF4 << 18 // vandi.b case AVORB: |
