ppc64/ppc64asm: add ISA 3.1B support

The new ISA fixes a couple typos, and adds special hashing
instructions to support ROP exploitation.

The hash instructions encode a negative offset in a novel
way which requires a bit of special handling.

Change-Id: I9491e10ac87efe37d93b6efaf7f108ae3a4402fd
Reviewed-on: https://go-review.googlesource.com/c/arch/+/418859
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Paul Murphy <murp@ibm.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
This commit is contained in:
Paul E. Murphy 2022-07-06 15:19:45 -05:00 коммит произвёл Paul Murphy
Родитель e1262b008e
Коммит 1bb480fc25
10 изменённых файлов: 141 добавлений и 33 удалений

Просмотреть файл

@ -1,4 +1,4 @@
# POWER ISA 3.1 instruction description.
# POWER ISA 3.1B instruction description.
#
# This file contains comment lines, each beginning with #,
# followed by entries in CSV format.
@ -13,8 +13,12 @@
# a list of sequences of the form (,sequence)+. A leading comma is used to signify an
# instruction encoding requiring multiple instruction words.
# The fourth field represents the ISA version where the instruction was introduced as
# stated in Appendix F. of ISA 3.1
# stated in Appendix F. of ISA 3.1B
#
"Hash Check X-form","hashchk RB,offset(RA)","31@0|D@6|RA@11|RB@16|754@21|DX@31|","v3.1B"
"Hash Check Privileged X-form","hashchkp RB,offset(RA)","31@0|D@6|RA@11|RB@16|690@21|DX@31|","v3.1B"
"Hash Store X-form","hashst RB,offset(RA)","31@0|D@6|RA@11|RB@16|722@21|DX@31|","v3.1B"
"Hash Store Privileged X-form","hashstp RB,offset(RA)","31@0|D@6|RA@11|RB@16|658@21|DX@31|","v3.1B"
"Byte-Reverse Doubleword X-form","brd RA,RS","31@0|RS@6|RA@11|///@16|187@21|/@31|","v3.1"
"Byte-Reverse Halfword X-form","brh RA,RS","31@0|RS@6|RA@11|///@16|219@21|/@31|","v3.1"
"Byte-Reverse Word X-form","brw RA,RS","31@0|RS@6|RA@11|///@16|155@21|/@31|","v3.1"
@ -209,7 +213,7 @@
"VSX Vector bfloat16 GER (Rank-2 Update) Negative multiply, Positive accumulate XX3-form","xvbf16ger2np AT,XA,XB","59@0|AT@6|//@9|A@11|B@16|114@21|AX@29|BX@30|/@31|","v3.1"
"VSX Vector bfloat16 GER (Rank-2 Update) Positive multiply, Negative accumulate XX3-form","xvbf16ger2pn AT,XA,XB","59@0|AT@6|//@9|A@11|B@16|178@21|AX@29|BX@30|/@31|","v3.1"
"VSX Vector bfloat16 GER (Rank-2 Update) Positive multiply, Positive accumulate XX3-form","xvbf16ger2pp AT,XA,XB","59@0|AT@6|//@9|A@11|B@16|50@21|AX@29|BX@30|/@31|","v3.1"
"VSX Vector Convert bfloat16 to Single-Precision format XX2-form","xvcvbf16spn XT,XB","60@0|T@6|16@11|B@16|475@21|BX@30|TX@31|","v3.1"
"VSX Vector Convert bfloat16 to Single-Precision format Non-signaling XX2-form","xvcvbf16spn XT,XB","60@0|T@6|16@11|B@16|475@21|BX@30|TX@31|","v3.1"
"VSX Vector Convert with round Single-Precision to bfloat16 format XX2-form","xvcvspbf16 XT,XB","60@0|T@6|17@11|B@16|475@21|BX@30|TX@31|","v3.1"
"VSX Vector 16-bit Floating-Point GER (rank-2 update) XX3-form","xvf16ger2 AT,XA,XB","59@0|AT@6|//@9|A@11|B@16|19@21|AX@29|BX@30|/@31|","v3.1"
"VSX Vector 16-bit Floating-Point GER (rank-2 update) Negative multiply, Negative accumulate XX3-form","xvf16ger2nn AT,XA,XB","59@0|AT@6|//@9|A@11|B@16|210@21|AX@29|BX@30|/@31|","v3.1"
@ -1034,7 +1038,7 @@
"Add Carrying XO-form","addc RT,RA,RB (OE=0 Rc=0)|addc. RT,RA,RB (OE=0 Rc=1)|addco RT,RA,RB (OE=1 Rc=0)|addco. RT,RA,RB (OE=1 Rc=1)","31@0|RT@6|RA@11|RB@16|OE@21|10@22|Rc@31|","P1"
"Add Extended XO-form","adde RT,RA,RB (OE=0 Rc=0)|adde. RT,RA,RB (OE=0 Rc=1)|addeo RT,RA,RB (OE=1 Rc=0)|addeo. RT,RA,RB (OE=1 Rc=1)","31@0|RT@6|RA@11|RB@16|OE@21|138@22|Rc@31|","P1"
"Add Immediate D-form","addi RT,RA,SI|li RT,SI (RA=0)","14@0|RT@6|RA@11|SI@16|","P1"
"Add Immediate Carrying D-formy","addic RT,RA,SI","12@0|RT@6|RA@11|SI@16|","P1"
"Add Immediate Carrying D-form","addic RT,RA,SI","12@0|RT@6|RA@11|SI@16|","P1"
"Add Immediate Carrying and Record D-form","addic. RT,RA,SI","13@0|RT@6|RA@11|SI@16|","P1"
"Add Immediate Shifted D-form","addis RT,RA,SI|lis RT,SI (RA=0)","15@0|RT@6|RA@11|SI@16|","P1"
"Add to Minus One Extended XO-form","addme RT,RA (OE=0 Rc=0)|addme. RT,RA (OE=0 Rc=1)|addmeo RT,RA (OE=1 Rc=0)|addmeo. RT,RA (OE=1 Rc=1)","31@0|RT@6|RA@11|///@16|OE@21|234@22|Rc@31|","P1"

Не удается отобразить этот файл, потому что он имеет неправильное количество полей в строке 3.

Просмотреть файл

@ -22,9 +22,12 @@ const prefixOpcode = 1
// The Args are stored in the same order as the instruction manual.
//
// Prefixed instructions are stored as:
// prefix << 32 | suffix,
//
// prefix << 32 | suffix,
//
// Regular instructions are:
// inst << 32
//
// inst << 32
type instFormat struct {
Op Op
Mask uint64
@ -77,6 +80,12 @@ func (a argField) Parse(i [2]uint32) Arg {
return Label(a.BitFields.ParseSigned(i) << a.Shift)
case TypeOffset:
return Offset(a.BitFields.ParseSigned(i) << a.Shift)
case TypeNegOffset:
// An oddball encoding of offset for hashchk and similar.
// e.g hashchk offset is 0b1111111000000000 | DX << 8 | D << 3
off := a.BitFields.ParseSigned(i) << a.Shift
neg := int64(-1) << (int(a.Shift) + a.BitFields.NumBits())
return Offset(neg | off)
}
}
@ -98,6 +107,7 @@ const (
TypeImmSigned // signed immediate
TypeImmUnsigned // unsigned immediate/flag/mask, this is the catch-all type
TypeOffset // signed offset in load/store
TypeNegOffset // A negative 16 bit value 0b1111111xxxxx000 encoded as 0bxxxxx (e.g in the hashchk instruction)
TypeLast // must be the last one
)
@ -135,6 +145,8 @@ func (t ArgType) String() string {
return "Label"
case TypeOffset:
return "Offset"
case TypeNegOffset:
return "NegOffset"
}
}

Просмотреть файл

@ -86,3 +86,12 @@ func (bs BitFields) ParseSigned(i [2]uint32) int64 {
u, l := bs.parse(i)
return int64(u) << (64 - l) >> (64 - l)
}
// Count the number of bits in the aggregate BitFields
func (bs BitFields) NumBits() int {
num := 0
for _, b := range bs {
num += int(b.Bits)
}
return num
}

Просмотреть файл

@ -65,26 +65,29 @@ func TestBitFields(t *testing.T) {
i [2]uint32 // input
u uint64 // unsigned output
s int64 // signed output
nb int // Total number of bits in BitField
fail bool // if the check should panic
}{
{BitFields{{0, 0, 1}}, [2]uint32{0, 0}, 0, 0, true},
{BitFields{{31, 2, 1}}, [2]uint32{0, 0}, 0, 0, true},
{BitFields{{31, 1, 1}}, [2]uint32{0, 1}, 1, -1, false},
{BitFields{{29, 2, 1}}, [2]uint32{0, 0 << 1}, 0, 0, false},
{BitFields{{29, 2, 1}}, [2]uint32{0, 1 << 1}, 1, 1, false},
{BitFields{{29, 2, 1}}, [2]uint32{0, 2 << 1}, 2, -2, false},
{BitFields{{29, 2, 1}}, [2]uint32{0, 3 << 1}, 3, -1, false},
{BitFields{{0, 32, 1}}, [2]uint32{0, 1<<32 - 1}, 1<<32 - 1, -1, false},
{BitFields{{16, 3, 1}}, [2]uint32{0, 1 << 15}, 4, -4, false},
{BitFields{{16, 16, 0}, {16, 16, 1}}, [2]uint32{0x8016, 0x32}, 0x80160032, -0x7FE9FFCE, false},
{BitFields{{14, 18, 0}, {16, 16, 1}}, [2]uint32{0x38016, 0x32}, 0x380160032, -0x07FE9FFCE, false},
{BitFields{{0, 0, 1}}, [2]uint32{0, 0}, 0, 0, 0, true},
{BitFields{{31, 2, 1}}, [2]uint32{0, 0}, 0, 0, 2, true},
{BitFields{{31, 1, 1}}, [2]uint32{0, 1}, 1, -1, 1, false},
{BitFields{{29, 2, 1}}, [2]uint32{0, 0 << 1}, 0, 0, 2, false},
{BitFields{{29, 2, 1}}, [2]uint32{0, 1 << 1}, 1, 1, 2, false},
{BitFields{{29, 2, 1}}, [2]uint32{0, 2 << 1}, 2, -2, 2, false},
{BitFields{{29, 2, 1}}, [2]uint32{0, 3 << 1}, 3, -1, 2, false},
{BitFields{{0, 32, 1}}, [2]uint32{0, 1<<32 - 1}, 1<<32 - 1, -1, 32, false},
{BitFields{{16, 3, 1}}, [2]uint32{0, 1 << 15}, 4, -4, 3, false},
{BitFields{{16, 16, 0}, {16, 16, 1}}, [2]uint32{0x8016, 0x32}, 0x80160032, -0x7FE9FFCE, 32, false},
{BitFields{{14, 18, 0}, {16, 16, 1}}, [2]uint32{0x38016, 0x32}, 0x380160032, -0x07FE9FFCE, 34, false},
}
for i, tst := range tests {
var (
ou uint64
os int64
ou uint64
os int64
onb int
)
failed := panicOrNot(func() {
onb = tst.b.NumBits()
ou = tst.b.Parse(tst.i)
os = tst.b.ParseSigned(tst.i)
})
@ -99,5 +102,8 @@ func TestBitFields(t *testing.T) {
if os != tst.s {
t.Errorf("case %d: %v.ParseSigned(%d) returned %d, expected %d", i, tst.b, tst.i, os, tst.s)
}
if onb != tst.nb {
t.Errorf("case %d: %v.NumBits() returned %d, expected %d", i, tst.b, onb, tst.nb)
}
}
}

Просмотреть файл

@ -83,7 +83,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
STH, STHU,
STW, STWU,
STD, STDU,
STQ, STFD, STFDU, STFS, STFSU:
STFD, STFDU,
STFS, STFSU,
STQ, HASHST, HASHSTP:
return op + " " + strings.Join(args, ",")
case FCMPU, FCMPO, CMPD, CMPDI, CMPLD, CMPLDI, CMPW, CMPWI, CMPLW, CMPLWI:

Просмотреть файл

@ -1,9 +1,13 @@
// Code generated by ppc64map -fmt=decoder pp64.csv DO NOT EDIT.
// Code generated by ppc64map -fmt=decoder ../pp64.csv DO NOT EDIT.
package ppc64asm
const (
_ Op = iota
HASHCHK
HASHCHKP
HASHST
HASHSTP
BRD
BRH
BRW
@ -1420,6 +1424,10 @@ const (
)
var opstr = [...]string{
HASHCHK: "hashchk",
HASHCHKP: "hashchkp",
HASHST: "hashst",
HASHSTP: "hashstp",
BRD: "brd",
BRH: "brh",
BRW: "brw",
@ -2836,9 +2844,10 @@ var opstr = [...]string{
}
var (
ap_Reg_16_20 = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
ap_NegOffset_31_31_6_10_shift3 = &argField{Type: TypeNegOffset, Shift: 3, BitFields: BitFields{{31, 1, 0}, {6, 5, 0}}}
ap_Reg_11_15 = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{11, 5, 0}}}
ap_Reg_6_10 = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
ap_Reg_16_20 = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
ap_FPReg_6_10 = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
ap_VecReg_16_20 = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
ap_VecReg_6_10 = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
@ -2942,6 +2951,14 @@ var (
)
var instFormats = [...]instFormat{
{HASHCHK, 0xfc0007fe00000000, 0x7c0005e400000000, 0x0, // Hash Check X-form (hashchk RB,offset(RA))
[6]*argField{ap_Reg_16_20, ap_NegOffset_31_31_6_10_shift3, ap_Reg_11_15}},
{HASHCHKP, 0xfc0007fe00000000, 0x7c00056400000000, 0x0, // Hash Check Privileged X-form (hashchkp RB,offset(RA))
[6]*argField{ap_Reg_16_20, ap_NegOffset_31_31_6_10_shift3, ap_Reg_11_15}},
{HASHST, 0xfc0007fe00000000, 0x7c0005a400000000, 0x0, // Hash Store X-form (hashst RB,offset(RA))
[6]*argField{ap_Reg_16_20, ap_NegOffset_31_31_6_10_shift3, ap_Reg_11_15}},
{HASHSTP, 0xfc0007fe00000000, 0x7c00052400000000, 0x0, // Hash Store Privileged X-form (hashstp RB,offset(RA))
[6]*argField{ap_Reg_16_20, ap_NegOffset_31_31_6_10_shift3, ap_Reg_11_15}},
{BRD, 0xfc0007fe00000000, 0x7c00017600000000, 0xf80100000000, // Byte-Reverse Doubleword X-form (brd RA,RS)
[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
{BRH, 0xfc0007fe00000000, 0x7c0001b600000000, 0xf80100000000, // Byte-Reverse Halfword X-form (brh RA,RS)
@ -3344,7 +3361,7 @@ var instFormats = [...]instFormat{
[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
{XVBF16GER2PP, 0xfc0007f800000000, 0xec00019000000000, 0x60000100000000, // VSX Vector bfloat16 GER (Rank-2 Update) Positive multiply, Positive accumulate XX3-form (xvbf16ger2pp AT,XA,XB)
[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
{XVCVBF16SPN, 0xfc1f07fc00000000, 0xf010076c00000000, 0x0, // VSX Vector Convert bfloat16 to Single-Precision format XX2-form (xvcvbf16spn XT,XB)
{XVCVBF16SPN, 0xfc1f07fc00000000, 0xf010076c00000000, 0x0, // VSX Vector Convert bfloat16 to Single-Precision format Non-signaling XX2-form (xvcvbf16spn XT,XB)
[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
{XVCVSPBF16, 0xfc1f07fc00000000, 0xf011076c00000000, 0x0, // VSX Vector Convert with round Single-Precision to bfloat16 format XX2-form (xvcvspbf16 XT,XB)
[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
@ -5334,7 +5351,7 @@ var instFormats = [...]instFormat{
[6]*argField{ap_Reg_6_10, ap_ImmSigned_16_31}},
{ADDI, 0xfc00000000000000, 0x3800000000000000, 0x0, // Add Immediate D-form (addi RT,RA,SI)
[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
{ADDIC, 0xfc00000000000000, 0x3000000000000000, 0x0, // Add Immediate Carrying D-formy (addic RT,RA,SI)
{ADDIC, 0xfc00000000000000, 0x3000000000000000, 0x0, // Add Immediate Carrying D-form (addic RT,RA,SI)
[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
{ADDICCC, 0xfc00000000000000, 0x3400000000000000, 0x0, // Add Immediate Carrying and Record D-form (addic. RT,RA,SI)
[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},

10
ppc64/ppc64asm/testdata/decode.txt поставляемый
Просмотреть файл

@ -873,3 +873,13 @@ fc811000| plan9 FCMPU F1,F2,CR1
7c2311b8| plan9 CFUGED R1,R2,R3
04100016e4820032| gnu .quad 0x4100016e4820032
0612000138820007| gnu .quad 0x612000138820007
7fe20de5| plan9 HASHCHK -8(R2),R1
7fe20da5| plan9 HASHST R1,-8(R2)
7c020de4| plan9 HASHCHK -512(R2),R1
7c020da4| plan9 HASHST R1,-512(R2)
7c020de5| plan9 HASHCHK -256(R2),R1
7c020da5| plan9 HASHST R1,-256(R2)
7fe115a5| plan9 HASHST R2,-8(R1)
7fe11525| plan9 HASHSTP R2,-8(R1)
7fe115e5| plan9 HASHCHK -8(R1),R2
7fe11565| plan9 HASHCHKP -8(R1),R2

15
ppc64/ppc64asm/testdata/decode_generated.txt поставляемый
Просмотреть файл

@ -1,3 +1,7 @@
7e0115e5| gnu hashchk r2,-128(r1)
7e011565| gnu hashchkp r2,-128(r1)
7e0115a5| gnu hashst r2,-128(r1)
7e011525| gnu hashstp r2,-128(r1)
7c610176| gnu brd r1,r3
7c6101b6| gnu brh r1,r3
7c610136| gnu brw r1,r3
@ -23,9 +27,9 @@ f03f0ad1| gnu lxvkq vs33,1
7c611138| gnu pdepd r1,r3,r2
7c611178| gnu pextd r1,r3,r2
0610001688800032| gnu plbz r4,1441842
60000000| gnu nop
04100016e4800032| gnu pld r4,1441842
06100016c8600032| gnu plfd f3,1441842
60000000| gnu nop
06100016c0600032| gnu plfs f3,1441842
06100016a8800032| gnu plha r4,1441842
06100016a0800032| gnu plhz r4,1441842
@ -240,7 +244,6 @@ f02d1769| gnu xxgenpcvwm vs33,v2,13
7f810162| gnu xxmtacc a7
0500000188232a4f| gnu xxpermx vs33,vs35,vs37,vs41,1
7f830162| gnu xxsetaccz a7
60000000| gnu nop
0500012380234567| gnu xxsplti32dx vs33,1,19088743
0500012380254567| gnu xxspltidp vs33,19088743
0500012380274567| gnu xxspltiw vs33,19088743
@ -1214,13 +1217,13 @@ fc60382d| gnu fsqrt. f3,f7
7c611079| gnu andc. r1,r3,r2
70610000| gnu andi. r1,r3,0
74610000| gnu andis. r1,r3,0
48000690| gnu b 0x1a90
48000690| gnu b 0x1a9c
48000692| gnu ba 0x690
48000691| gnu bl 0x1a98
48000691| gnu bl 0x1aa4
48000693| gnu bla 0x690
40860690| gnu bne cr1,0x1aa0
40860690| gnu bne cr1,0x1aac
40860692| gnu bnea cr1,0x690
40860691| gnu bnel cr1,0x1aa8
40860691| gnu bnel cr1,0x1ab4
40860693| gnu bnela cr1,0x690
4c860420| gnu bnectr cr1
4c860421| gnu bnectrl cr1

Просмотреть файл

@ -60,6 +60,7 @@ const (
ISA_V30B
ISA_V30C
ISA_V31
ISA_V31B
)
var isaToISA = map[string]isaversion{
@ -77,6 +78,7 @@ var isaToISA = map[string]isaversion{
"v3.0B": ISA_V30B,
"v3.0C": ISA_V30C,
"v3.1": ISA_V31,
"v3.1B": ISA_V31B,
}
func usage() {
@ -482,6 +484,18 @@ func add(p *Prog, text, mnemonics, encoding, isa string) {
opr = "BD"
}
case "offset":
switch inst.Op {
// These encode a 6 bit displacement in the format of an X-form opcode.
// Allowable displaments are -8 to -8*64 in 8B increments.
case "hashchk", "hashchkp", "hashst", "hashstp":
typ = asm.TypeNegOffset
opr = "DX"
opr2 = "D"
shift = 3
}
case "XMSK", "YMSK", "PMSK", "IX", "BHRBE":
typ = asm.TypeImmUnsigned
@ -737,7 +751,12 @@ var isNotMemopMap = map[string]bool{
}
// Some ISA instructions are memops, but are not described like "Load ..." or "Store ..."
var isMemopMap = map[string]bool{}
var isMemopMap = map[string]bool{
"hashst": true,
"hashstp": true,
"hashchk": true,
"hashchkp": true,
}
// Does this instruction contain a memory argument (e.g x-form load or d-form store)
func hasMemoryArg(insn *Inst) bool {
@ -767,7 +786,7 @@ func insnEncFuncStr(insn *Inst, firstName [2]string) string {
// Does this field require an obj.Addr.Offset?
isImmediate := func(t asm.ArgType) bool {
return t == asm.TypeImmUnsigned || t == asm.TypeSpReg || t == asm.TypeImmSigned || t == asm.TypeOffset
return t == asm.TypeImmUnsigned || t == asm.TypeSpReg || t == asm.TypeImmSigned || t == asm.TypeOffset || t == asm.TypeNegOffset
}
if insn.memOp {
@ -827,13 +846,26 @@ func insnEncFuncStr(insn *Inst, firstName [2]string) string {
// Generate a check to verify shifted inputs satisfy their constraints.
// For historical reasons this is not needed for 16 bit values shifted by 16. (i.e SI/UI constants in addis/xoris)
if atype.Shift != 0 && atype.Shift != 16 && bits != 32 {
if atype.Type != asm.TypeNegOffset && atype.Shift != 0 && atype.Shift != 16 && bits != 32 {
arg := argOrder[j] + itype
mod := (1 << atype.Shift) - 1
errCheck += fmt.Sprintf("if %s & 0x%x != 0 {\n", arg, mod)
errCheck += fmt.Sprintf("c.ctxt.Diag(\"Constant 0x%%x (%%d) is not a multiple of %d\\n%%v\",%s,%s,p)\n", mod+1, arg, arg)
errCheck += fmt.Sprintf("}\n")
}
// NegOffset requires a stronger offset check
if atype.Type == asm.TypeNegOffset {
arg := argOrder[j] + itype
mask := -1 << (atype.BitFields.NumBits() + int(atype.Shift))
maskl := mask // Sign bits are implied in this type.
mask |= (1 << atype.Shift) - 1
min := maskl
max := maskl | (^mask)
step := 1 << atype.Shift
errCheck += fmt.Sprintf("if %s & 0x%x != 0x%x {\n", arg, uint32(mask), uint32(maskl))
errCheck += fmt.Sprintf("c.ctxt.Diag(\"Constant(%%d) must within the range of [%d,%d] in steps of %d\\n%%v\",%s,p)\n", min, max, step, arg)
errCheck += fmt.Sprintf("}\n")
}
j++
}
buf.WriteString(errCheck)
@ -895,6 +927,8 @@ func insnTypeStr(insn *Inst, uniqueRegTypes bool) string {
if atype.Shift != 0 {
ret += fmt.Sprintf("%d", atype.Shift)
}
case asm.TypeNegOffset: // e.g offset in hashst rb, offset(ra)
ret += "N"
default:
log.Fatalf("Unhandled type in insnTypeStr: %v\n", atype)
}
@ -953,6 +987,14 @@ func genOptabEntry(ta *AggInfo, typeMap map[string]*Inst) string {
shift = ""
}
}
if f.Type == asm.TypeNegOffset {
// This is a hack, but allows hashchk and like to correctly
// merge there argument into a C_SOREG memory location type
// argument a little later.
sign = "S"
bits = 16
shift = ""
}
return fmt.Sprintf("C_%s%d%sCON", sign, bits, shift)
}
insn := ta.Insns[0]

Просмотреть файл

@ -129,6 +129,9 @@
#define Rpfx 1
#define SIpfx 0xFFFFFFFE00010007
// A valid displacement value for the hash check and hash store instructions.
#define offset -128
// These decode as m.fpr* or m.vr*. This is a matter of preference. We
// don't support these mnemonics, and I don't think they improve reading
// disassembled code in most cases. so ignore.