mirror of
https://github.com/golang/go
synced 2024-10-14 20:05:36 +00:00
cmd/internal/obj/arm64: reclassify 32-bit/64-bit constants
Current assembler saves constants in Offset which type is int64, causing 32-bit constants have a incorrect class. This CL reclassifies constants when opcodes are 32-bit variant, like MOVW, ANDW and ADDW, etc. Besides, this CL encodes some constants of ADDCON class as MOVs instructions. This CL changes the assembler behavior as follows. 1. go assembler ADDW $MOVCON, Rn, Rd previous version: MOVD $MOVCON, Rtmp; ADDW Rtmp, Rn, Rd current version: MOVW $MOVCON, Rtmp; ADDW Rtmp, Rn, Rd 2. go assembly MOVW $0xaaaaffff, R1 previous version: treats $0xaaaaffff as VCON, encodes it as MOVW 0x994, R1 (loads it from pool). current version: treats $0xaaaaffff as MOVCON, and encodes it into MOVW instructions. 3. go assembly MOVD $0x210000, R1 previous version: treats $0x210000 as ADDCON, loads it from pool current version: treats $0x210000 as MOVCON, and encodes it into MOVD instructions. Add the test cases. 1. Binary size before/after. binary size change pkg/linux_arm64 -1.534KB pkg/tool/linux_arm64 -0.718KB go -0.32KB gofmt no change 2. go1 benchmark result. name old time/op new time/op delta BinaryTree17-8 6.26s ± 1% 6.28s ± 1% ~ (p=0.105 n=10+10) Fannkuch11-8 5.40s ± 0% 5.39s ± 0% -0.29% (p=0.028 n=9+10) FmtFprintfEmpty-8 94.5ns ± 0% 95.0ns ± 0% +0.51% (p=0.000 n=10+9) FmtFprintfString-8 163ns ± 1% 159ns ± 1% -2.06% (p=0.000 n=10+9) FmtFprintfInt-8 200ns ± 1% 196ns ± 1% -1.99% (p=0.000 n=9+10) FmtFprintfIntInt-8 292ns ± 3% 284ns ± 1% -2.87% (p=0.001 n=10+9) FmtFprintfPrefixedInt-8 422ns ± 1% 420ns ± 1% -0.59% (p=0.015 n=10+10) FmtFprintfFloat-8 458ns ± 0% 463ns ± 1% +1.19% (p=0.000 n=9+10) FmtManyArgs-8 1.37µs ± 1% 1.35µs ± 1% -1.85% (p=0.000 n=10+10) GobDecode-8 15.5ms ± 1% 15.3ms ± 1% -1.82% (p=0.000 n=10+10) GobEncode-8 11.7ms ± 5% 11.7ms ± 2% ~ (p=0.549 n=10+9) Gzip-8 622ms ± 0% 624ms ± 0% +0.23% (p=0.000 n=10+9) Gunzip-8 73.6ms ± 0% 73.8ms ± 1% ~ (p=0.077 n=9+9) HTTPClientServer-8 115µs ± 1% 115µs ± 1% ~ (p=0.796 n=10+10) JSONEncode-8 31.1ms ± 2% 28.7ms ± 1% -7.98% (p=0.000 n=10+9) JSONDecode-8 145ms ± 0% 145ms ± 1% ~ (p=0.447 n=9+10) Mandelbrot200-8 9.67ms ± 0% 9.60ms ± 0% -0.76% (p=0.000 n=9+9) GoParse-8 7.56ms ± 1% 7.58ms ± 0% +0.21% (p=0.035 n=10+9) RegexpMatchEasy0_32-8 208ns ±10% 222ns ± 0% ~ (p=0.531 n=10+6) RegexpMatchEasy0_1K-8 699ns ± 4% 694ns ± 4% ~ (p=0.868 n=10+10) RegexpMatchEasy1_32-8 186ns ± 8% 190ns ±12% ~ (p=0.955 n=10+10) RegexpMatchEasy1_1K-8 1.13µs ± 1% 1.05µs ± 2% -6.64% (p=0.000 n=10+10) RegexpMatchMedium_32-8 316ns ± 7% 288ns ± 1% -8.68% (p=0.000 n=10+7) RegexpMatchMedium_1K-8 90.2µs ± 0% 85.5µs ± 2% -5.19% (p=0.000 n=10+10) RegexpMatchHard_32-8 5.53µs ± 0% 3.90µs ± 0% -29.52% (p=0.000 n=10+10) RegexpMatchHard_1K-8 119µs ± 0% 124µs ± 0% +4.29% (p=0.000 n=9+10) Revcomp-8 1.07s ± 0% 1.07s ± 0% ~ (p=0.094 n=9+9) Template-8 162ms ± 1% 160ms ± 2% ~ (p=0.089 n=10+10) TimeParse-8 756ns ± 2% 763ns ± 1% ~ (p=0.158 n=10+10) TimeFormat-8 758ns ± 1% 746ns ± 1% -1.52% (p=0.000 n=10+10) name old speed new speed delta GobDecode-8 49.4MB/s ± 1% 50.3MB/s ± 1% +1.84% (p=0.000 n=10+10) GobEncode-8 65.6MB/s ± 5% 65.4MB/s ± 2% ~ (p=0.549 n=10+9) Gzip-8 31.2MB/s ± 0% 31.1MB/s ± 0% -0.24% (p=0.000 n=9+9) Gunzip-8 264MB/s ± 0% 263MB/s ± 1% ~ (p=0.073 n=9+9) JSONEncode-8 62.3MB/s ± 2% 67.7MB/s ± 1% +8.67% (p=0.000 n=10+9) JSONDecode-8 13.4MB/s ± 0% 13.4MB/s ± 1% ~ (p=0.508 n=9+10) GoParse-8 7.66MB/s ± 1% 7.64MB/s ± 0% -0.23% (p=0.049 n=10+9) RegexpMatchEasy0_32-8 154MB/s ± 9% 143MB/s ± 3% ~ (p=0.303 n=10+7) RegexpMatchEasy0_1K-8 1.46GB/s ± 4% 1.47GB/s ± 4% ~ (p=0.912 n=10+10) RegexpMatchEasy1_32-8 172MB/s ± 9% 170MB/s ±12% ~ (p=0.971 n=10+10) RegexpMatchEasy1_1K-8 908MB/s ± 1% 972MB/s ± 2% +7.12% (p=0.000 n=10+10) RegexpMatchMedium_32-8 3.17MB/s ± 7% 3.46MB/s ± 1% +9.14% (p=0.000 n=10+7) RegexpMatchMedium_1K-8 11.3MB/s ± 0% 12.0MB/s ± 2% +5.51% (p=0.000 n=10+10) RegexpMatchHard_32-8 5.78MB/s ± 0% 8.21MB/s ± 0% +41.93% (p=0.000 n=9+10) RegexpMatchHard_1K-8 8.62MB/s ± 0% 8.27MB/s ± 0% -4.11% (p=0.000 n=9+10) Revcomp-8 237MB/s ± 0% 237MB/s ± 0% ~ (p=0.081 n=9+9) Template-8 12.0MB/s ± 1% 12.1MB/s ± 2% ~ (p=0.072 n=10+10) Change-Id: I080801f520366b42d5f9699954bd33106976a81b Reviewed-on: https://go-review.googlesource.com/c/120661 Run-TryBot: Ben Shi <powerman1st@163.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
1e8ecefcd5
commit
86ce1cb060
30
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
30
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
|
@ -191,6 +191,11 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
|||
FMOVD F4, (R2)(R6) // FMOVD F4, (R2)(R6*1) // 446826fc
|
||||
FMOVD F4, (R2)(R6<<3) // 447826fc
|
||||
|
||||
CMPW $40960, R0 // 1f284071
|
||||
CMPW $27745, R2 // 3b8c8d525f001b6b
|
||||
CMNW $0x3fffffc0, R2 // CMNW $1073741760, R2 // fb5f1a325f001b2b
|
||||
CMPW $0xffff0, R1 // CMPW $1048560, R1 // fb3f1c323f001b6b
|
||||
ADD $0x3fffffffc000, R5 // ADD $70368744161280, R5 // fb7f72b2a5001b8b
|
||||
// LTYPE1 imsr ',' spreg ','
|
||||
// {
|
||||
// outcode($1, &$2, $4, &nullgen);
|
||||
|
@ -226,6 +231,16 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
|||
ANDS $0x22220000, R3, R4 // ANDS $572653568, R3, R4 // 5b44a4d264001bea
|
||||
BICS $0x22220000, R3, R4 // BICS $572653568, R3, R4 // 5b44a4d264003bea
|
||||
|
||||
EOR $0xe03fffffffffffff, R20, R22 // EOR $-2287828610704211969, R20, R22 // 96e243d2
|
||||
TSTW $0x600000006, R1 // TSTW $25769803782, R1 // 3f041f72
|
||||
ANDS $0xffff, R2 // ANDS $65535, R2 // 423c40f2
|
||||
AND $0x7fffffff, R3 // AND $2147483647, R3 // 63784092
|
||||
ANDS $0x0ffffffff80000000, R2 // ANDS $-2147483648, R2 // 428061f2
|
||||
AND $0xfffff, R2 // AND $1048575, R2 // 424c4092
|
||||
ANDW $0xf00fffff, R1 // ANDW $4027580415, R1 // 215c0412
|
||||
ANDSW $0xff00ffff, R1 // ANDSW $4278255615, R1 // 215c0872
|
||||
TSTW $0xff00ff, R1 // TSTW $16711935, R1 // 3f9c0072
|
||||
|
||||
AND $8, R0, RSP // 1f007d92
|
||||
ORR $8, R0, RSP // 1f007db2
|
||||
EOR $8, R0, RSP // 1f007dd2
|
||||
|
@ -233,6 +248,19 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
|||
ORN $8, R0, RSP // 1ff87cb2
|
||||
EON $8, R0, RSP // 1ff87cd2
|
||||
|
||||
MOVD $0x3fffffffc000, R0 // MOVD $70368744161280, R0 // e07f72b2
|
||||
MOVW $0xaaaa0000, R1 // MOVW $2863267840, R1 // 4155b552
|
||||
MOVW $0xaaaaffff, R1 // MOVW $2863333375, R1 // a1aaaa12
|
||||
MOVW $0xaaaa, R1 // MOVW $43690, R1 // 41559552
|
||||
MOVW $0xffffaaaa, R1 // MOVW $4294945450, R1 // a1aa8a12
|
||||
MOVW $0xffff0000, R1 // MOVW $4294901760, R1 // e1ffbf52
|
||||
MOVD $0xffff00000000000, R1 // MOVD $1152903912420802560, R1 // e13f54b2
|
||||
MOVD $0x11110000, R1 // MOVD $286326784, R1 // 2122a2d2
|
||||
MOVD $0, R1 // 010080d2
|
||||
MOVD $-1, R1 // 01008092
|
||||
MOVD $0x210000, R0 // MOVD $2162688, R0 // 2004a0d2
|
||||
MOVD $0xffffffffffffaaaa, R1 // MOVD $-21846, R1 // a1aa8a92
|
||||
|
||||
//
|
||||
// CLS
|
||||
//
|
||||
|
@ -428,7 +456,7 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
|||
CMP R22.SXTX, RSP // ffe336eb
|
||||
|
||||
CMP $0x22220000, RSP // CMP $572653568, RSP // 5b44a4d2ff633beb
|
||||
CMPW $0x22220000, RSP // CMPW $572653568, RSP // 5b44a4d2ff633b6b
|
||||
CMPW $0x22220000, RSP // CMPW $572653568, RSP // 5b44a452ff633b6b
|
||||
|
||||
// TST
|
||||
TST $15, R2 // 5f0c40f2
|
||||
|
|
|
@ -407,6 +407,7 @@ const (
|
|||
C_ABCON0 // could be C_ADDCON0 or C_BITCON
|
||||
C_ADDCON0 // 12-bit unsigned, unshifted
|
||||
C_ABCON // could be C_ADDCON or C_BITCON
|
||||
C_AMCON // could be C_ADDCON or C_MOVCON
|
||||
C_ADDCON // 12-bit unsigned, shifted left by 0 or 12
|
||||
C_MBCON // could be C_MOVCON or C_BITCON
|
||||
C_MOVCON // generated by a 16-bit constant, optionally inverted and/or shifted by multiple of 16
|
||||
|
|
|
@ -23,6 +23,7 @@ var cnames7 = []string{
|
|||
"ABCON0",
|
||||
"ADDCON0",
|
||||
"ABCON",
|
||||
"AMCON",
|
||||
"ADDCON",
|
||||
"MBCON",
|
||||
"MOVCON",
|
||||
|
|
|
@ -164,6 +164,10 @@ func OPBIT(x uint32) uint32 {
|
|||
return 1<<30 | 0<<29 | 0xD6<<21 | 0<<16 | x<<10
|
||||
}
|
||||
|
||||
func MOVCONST(d int64, s int, rt int) uint32 {
|
||||
return uint32(((d>>uint(s*16))&0xFFFF)<<5) | uint32(s)&3<<21 | uint32(rt&31)
|
||||
}
|
||||
|
||||
const (
|
||||
LFROM = 1 << 0
|
||||
LTO = 1 << 1
|
||||
|
@ -272,12 +276,10 @@ var optab = []Optab{
|
|||
/* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */
|
||||
{AMOVW, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
|
||||
{AMOVD, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
|
||||
|
||||
// TODO: these don't work properly.
|
||||
// { AMOVW, C_ADDCON, C_NONE, C_REG, 2, 4, 0 , 0},
|
||||
// { AMOVD, C_ADDCON, C_NONE, C_REG, 2, 4, 0 , 0},
|
||||
{AMOVW, C_BITCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
|
||||
{AMOVD, C_BITCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
|
||||
{AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
|
||||
{AMOVD, C_VCON, C_NONE, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
|
||||
|
||||
{AMOVK, C_VCON, C_NONE, C_NONE, C_REG, 33, 4, 0, 0, 0},
|
||||
{AMOVD, C_AACON, C_NONE, C_NONE, C_REG, 4, 4, REGFROM, 0, 0},
|
||||
|
@ -318,9 +320,7 @@ var optab = []Optab{
|
|||
{AWORD, C_NONE, C_NONE, C_NONE, C_LCON, 14, 4, 0, 0, 0},
|
||||
{AWORD, C_NONE, C_NONE, C_NONE, C_LEXT, 14, 4, 0, 0, 0},
|
||||
{AWORD, C_NONE, C_NONE, C_NONE, C_ADDR, 14, 4, 0, 0, 0},
|
||||
{AMOVW, C_VCON, C_NONE, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
|
||||
{AMOVW, C_VCONADDR, C_NONE, C_NONE, C_REG, 68, 8, 0, 0, 0},
|
||||
{AMOVD, C_VCON, C_NONE, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
|
||||
{AMOVD, C_VCONADDR, C_NONE, C_NONE, C_REG, 68, 8, 0, 0, 0},
|
||||
{AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
|
||||
{AMOVBU, C_REG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
|
||||
|
@ -1105,6 +1105,23 @@ func isSTXPop(op obj.As) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func isANDWop(op obj.As) bool {
|
||||
switch op {
|
||||
case AANDW, AORRW, AEORW, AANDSW, ATSTW,
|
||||
ABICW, AEONW, AORNW, ABICSW:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isADDWop(op obj.As) bool {
|
||||
switch op {
|
||||
case AADDW, AADDSW, ASUBW, ASUBSW, ACMNW, ACMPW:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isRegShiftOrExt(a *obj.Addr) bool {
|
||||
return (a.Index-obj.RBaseARM64)®_EXT != 0 || (a.Index-obj.RBaseARM64)®_LSL != 0
|
||||
}
|
||||
|
@ -1411,6 +1428,52 @@ func rclass(r int16) int {
|
|||
return C_GOK
|
||||
}
|
||||
|
||||
// con32class reclassifies the constant of 32-bit instruction. Becuase the constant type is 32-bit,
|
||||
// but saved in Offset which type is int64, con32class treats it as uint32 type and reclassifies it.
|
||||
func (c *ctxt7) con32class(a *obj.Addr) int {
|
||||
v := uint32(a.Offset)
|
||||
if v == 0 {
|
||||
return C_ZCON
|
||||
}
|
||||
if isaddcon(int64(v)) {
|
||||
if v <= 0xFFF {
|
||||
if isbitcon(uint64(v)) {
|
||||
return C_ABCON0
|
||||
}
|
||||
return C_ADDCON0
|
||||
}
|
||||
if isbitcon(uint64(v)) {
|
||||
return C_ABCON
|
||||
}
|
||||
return C_ADDCON
|
||||
}
|
||||
|
||||
t := movcon(int64(v))
|
||||
if t >= 0 {
|
||||
if isbitcon(uint64(v)) {
|
||||
return C_MBCON
|
||||
}
|
||||
return C_MOVCON
|
||||
}
|
||||
|
||||
t = movcon(int64(^v))
|
||||
if t >= 0 {
|
||||
if isbitcon(uint64(v)) {
|
||||
return C_MBCON
|
||||
}
|
||||
return C_MOVCON
|
||||
}
|
||||
|
||||
if isbitcon(uint64(v)) {
|
||||
return C_BITCON
|
||||
}
|
||||
|
||||
if 0 <= v && v <= 0xffffff {
|
||||
return C_ADDCON2
|
||||
}
|
||||
return C_LCON
|
||||
}
|
||||
|
||||
func (c *ctxt7) aclass(a *obj.Addr) int {
|
||||
switch a.Type {
|
||||
case obj.TYPE_NONE:
|
||||
|
@ -1517,6 +1580,12 @@ func (c *ctxt7) aclass(a *obj.Addr) int {
|
|||
if isbitcon(uint64(v)) {
|
||||
return C_ABCON
|
||||
}
|
||||
if movcon(v) >= 0 {
|
||||
return C_AMCON
|
||||
}
|
||||
if movcon(^v) >= 0 {
|
||||
return C_AMCON
|
||||
}
|
||||
return C_ADDCON
|
||||
}
|
||||
|
||||
|
@ -1609,6 +1678,34 @@ func (c *ctxt7) oplook(p *obj.Prog) *Optab {
|
|||
}
|
||||
a1 = a0 + 1
|
||||
p.From.Class = int8(a1)
|
||||
// more specific classification of 32-bit integers
|
||||
if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE {
|
||||
if p.As == AMOVW || isADDWop(p.As) {
|
||||
ra0 := c.con32class(&p.From)
|
||||
// do not break C_ADDCON2 when S bit is set
|
||||
if (p.As == AADDSW || p.As == ASUBSW) && ra0 == C_ADDCON2 {
|
||||
ra0 = C_LCON
|
||||
}
|
||||
a1 = ra0 + 1
|
||||
p.From.Class = int8(a1)
|
||||
}
|
||||
if isANDWop(p.As) {
|
||||
switch p.As {
|
||||
case AANDW, AORRW, AEORW, AANDSW, ATSTW:
|
||||
// For 32-bit logical instruction with constant,
|
||||
// rewrite the high 32-bit to be a copy of the low
|
||||
// 32-bit, so that the BITCON test can be shared
|
||||
// for both 32-bit and 64-bit.
|
||||
if a0 == C_BITCON {
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
a1 = c.con32class(&p.From) + 1
|
||||
p.From.Class = int8(a1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a1--
|
||||
|
@ -1679,7 +1776,7 @@ func cmp(a int, b int) bool {
|
|||
}
|
||||
|
||||
case C_ADDCON:
|
||||
if b == C_ZCON || b == C_ABCON0 || b == C_ADDCON0 || b == C_ABCON {
|
||||
if b == C_ZCON || b == C_ABCON0 || b == C_ADDCON0 || b == C_ABCON || b == C_AMCON {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -1689,7 +1786,7 @@ func cmp(a int, b int) bool {
|
|||
}
|
||||
|
||||
case C_MOVCON:
|
||||
if b == C_MBCON || b == C_ZCON || b == C_ADDCON0 {
|
||||
if b == C_MBCON || b == C_ZCON || b == C_ADDCON0 || b == C_AMCON {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -1699,7 +1796,7 @@ func cmp(a int, b int) bool {
|
|||
}
|
||||
|
||||
case C_LCON:
|
||||
if b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_ABCON0 || b == C_MBCON || b == C_MOVCON || b == C_ADDCON2 {
|
||||
if b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_ABCON0 || b == C_MBCON || b == C_MOVCON || b == C_ADDCON2 || b == C_AMCON {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -3501,8 +3598,8 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
|||
if r == 0 {
|
||||
r = rt
|
||||
}
|
||||
o1 = c.oaddi(p, int32(op), int32(c.regoff(&p.From)) & 0x000fff, r, rt)
|
||||
o2 = c.oaddi(p, int32(op), int32(c.regoff(&p.From)) & 0xfff000, rt, rt)
|
||||
o1 = c.oaddi(p, int32(op), int32(c.regoff(&p.From))&0x000fff, r, rt)
|
||||
o2 = c.oaddi(p, int32(op), int32(c.regoff(&p.From))&0xfff000, rt, rt)
|
||||
|
||||
case 50: /* sys/sysl */
|
||||
o1 = c.opirr(p, p.As)
|
||||
|
@ -3670,7 +3767,11 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
|||
if p.Reg == REGTMP {
|
||||
c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
|
||||
}
|
||||
o1 = c.omovconst(AMOVD, p, &p.From, REGTMP)
|
||||
if isADDWop(p.As) || isANDWop(p.As) {
|
||||
o1 = c.omovconst(AMOVW, p, &p.From, REGTMP)
|
||||
} else {
|
||||
o1 = c.omovconst(AMOVD, p, &p.From, REGTMP)
|
||||
}
|
||||
|
||||
rt := int(p.To.Reg)
|
||||
if p.To.Type == obj.TYPE_NONE {
|
||||
|
@ -6195,31 +6296,37 @@ func (c *ctxt7) omovconst(as obj.As, p *obj.Prog, a *obj.Addr, rt int) (o1 uint3
|
|||
return o1
|
||||
}
|
||||
|
||||
r := 32
|
||||
if as == AMOVD {
|
||||
r = 64
|
||||
}
|
||||
d := a.Offset
|
||||
s := movcon(d)
|
||||
if s < 0 || s >= r {
|
||||
d = ^d
|
||||
s = movcon(d)
|
||||
if s < 0 || s >= r {
|
||||
c.ctxt.Diag("impossible move wide: %#x\n%v", uint64(a.Offset), p)
|
||||
}
|
||||
if as == AMOVD {
|
||||
o1 = c.opirr(p, AMOVN)
|
||||
} else {
|
||||
if as == AMOVW {
|
||||
d := uint32(a.Offset)
|
||||
s := movcon(int64(d))
|
||||
if s < 0 || 16*s >= 32 {
|
||||
d = ^d
|
||||
s = movcon(int64(d))
|
||||
if s < 0 || 16*s >= 32 {
|
||||
c.ctxt.Diag("impossible 32-bit move wide: %#x\n%v", uint32(a.Offset), p)
|
||||
}
|
||||
o1 = c.opirr(p, AMOVNW)
|
||||
}
|
||||
} else {
|
||||
if as == AMOVD {
|
||||
o1 = c.opirr(p, AMOVZ)
|
||||
} else {
|
||||
o1 = c.opirr(p, AMOVZW)
|
||||
}
|
||||
o1 |= MOVCONST(int64(d), s, rt)
|
||||
}
|
||||
o1 |= uint32((((d >> uint(s*16)) & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31))
|
||||
if as == AMOVD {
|
||||
d := a.Offset
|
||||
s := movcon(d)
|
||||
if s < 0 || 16*s >= 64 {
|
||||
d = ^d
|
||||
s = movcon(d)
|
||||
if s < 0 || 16*s >= 64 {
|
||||
c.ctxt.Diag("impossible 64-bit move wide: %#x\n%v", uint64(a.Offset), p)
|
||||
}
|
||||
o1 = c.opirr(p, AMOVN)
|
||||
} else {
|
||||
o1 = c.opirr(p, AMOVZ)
|
||||
}
|
||||
o1 |= MOVCONST(d, s, rt)
|
||||
}
|
||||
|
||||
return o1
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue