@@ -416,8 +416,8 @@ var optab = []Optab{
416
416
417
417
{AVMOVQ , C_ELEM , C_NONE , C_NONE , C_ARNG , C_NONE , 45 , 4 , 0 , 0 },
418
418
419
- {APRELD , C_SOREG , C_NONE , C_U5CON , C_NONE , C_NONE , 46 , 4 , 0 , 0 },
420
- {APRELDX , C_ROFF , C_NONE , C_U5CON , C_NONE , C_NONE , 47 , 4 , 0 , 0 },
419
+ {APRELD , C_SOREG , C_U5CON , C_NONE , C_NONE , C_NONE , 46 , 4 , 0 , 0 },
420
+ {APRELDX , C_SOREG , C_DCON , C_U5CON , C_NONE , C_NONE , 47 , 20 , 0 , 0 },
421
421
422
422
{obj .APCALIGN , C_U12CON , C_NONE , C_NONE , C_NONE , C_NONE , 0 , 0 , 0 , 0 },
423
423
{obj .APCDATA , C_32CON , C_NONE , C_NONE , C_32CON , C_NONE , 0 , 0 , 0 , 0 },
@@ -1105,6 +1105,22 @@ func (c *ctxt0) oplook(p *obj.Prog) *Optab {
1105
1105
c .ctxt .Diag ("loong64 ops not initialized, call loong64.buildop first" )
1106
1106
}
1107
1107
1108
+ restArgsIndex := 0
1109
+ restArgsLen := len (p .RestArgs )
1110
+ if restArgsLen > 2 {
1111
+ c .ctxt .Diag ("too many RestArgs: got %v, maximum is 2\n " , restArgsLen )
1112
+ return nil
1113
+ }
1114
+
1115
+ restArgsv := [2 ]int {C_NONE + 1 , C_NONE + 1 }
1116
+ for i , ap := range p .RestArgs {
1117
+ restArgsv [i ] = int (ap .Addr .Class )
1118
+ if restArgsv [i ] == 0 {
1119
+ restArgsv [i ] = c .aclass (& ap .Addr ) + 1
1120
+ ap .Addr .Class = int8 (restArgsv [i ])
1121
+ }
1122
+ }
1123
+
1108
1124
a1 := int (p .Optab )
1109
1125
if a1 != 0 {
1110
1126
return & optab [a1 - 1 ]
@@ -1130,6 +1146,9 @@ func (c *ctxt0) oplook(p *obj.Prog) *Optab {
1130
1146
a2 := C_NONE
1131
1147
if p .Reg != 0 {
1132
1148
a2 = c .rclass (p .Reg )
1149
+ } else if restArgsLen > 0 {
1150
+ a2 = restArgsv [restArgsIndex ] - 1
1151
+ restArgsIndex ++
1133
1152
}
1134
1153
1135
1154
// 2nd destination operand
@@ -1140,22 +1159,20 @@ func (c *ctxt0) oplook(p *obj.Prog) *Optab {
1140
1159
1141
1160
// 3rd source operand
1142
1161
a3 := C_NONE
1143
- if len (p .RestArgs ) > 0 {
1144
- a3 = int (p .RestArgs [0 ].Class )
1145
- if a3 == 0 {
1146
- a3 = c .aclass (& p .RestArgs [0 ].Addr ) + 1
1147
- p .RestArgs [0 ].Class = int8 (a3 )
1148
- }
1149
- a3 --
1162
+ if restArgsLen > 0 && restArgsIndex < restArgsLen {
1163
+ a3 = restArgsv [restArgsIndex ] - 1
1164
+ restArgsIndex ++
1150
1165
}
1151
1166
1152
1167
ops := oprange [p .As & obj .AMask ]
1153
1168
c1 := & xcmp [a1 ]
1169
+ c2 := & xcmp [a2 ]
1154
1170
c3 := & xcmp [a3 ]
1155
1171
c4 := & xcmp [a4 ]
1172
+ c5 := & xcmp [a5 ]
1156
1173
for i := range ops {
1157
1174
op := & ops [i ]
1158
- if ( int ( op .reg ) == a2 ) && c3 [op .from3 ] && c1 [op .from1 ] && c4 [op .to1 ] && ( int ( op .to2 ) == a5 ) {
1175
+ if c1 [ op .from1 ] && c2 [op .reg ] && c3 [op .from3 ] && c4 [op .to1 ] && c5 [ op .to2 ] {
1159
1176
p .Optab = uint16 (cap (optab ) - cap (ops ) + i + 1 )
1160
1177
return op
1161
1178
}
@@ -2457,16 +2474,40 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
2457
2474
c .checkindex (p , index , m )
2458
2475
o1 = v | (index << 10 ) | (vj << 5 ) | vd
2459
2476
2460
- case 46 :
2461
- // preld offset(Rbase), hint
2477
+ case 46 : // preld offset(Rbase), $hint
2462
2478
offs := c .regoff (& p .From )
2463
2479
hint := p .GetFrom3 ().Offset
2464
2480
o1 = OP_12IR_5I (c .opiir (p .As ), uint32 (offs ), uint32 (p .From .Reg ), uint32 (hint ))
2465
2481
2466
- case 47 :
2467
- // preldx (Rbase)(Roff), hint
2468
- hint := p .GetFrom3 ().Offset
2469
- o1 = OP_5IRR (c .opirr (p .As ), uint32 (p .From .Index ), uint32 (p .From .Reg ), uint32 (hint ))
2482
+ case 47 : // preldx offset(Rbase), $n, $hint
2483
+ offs := c .regoff (& p .From )
2484
+ hint := p .RestArgs [1 ].Offset
2485
+ n := uint64 (p .GetFrom3 ().Offset )
2486
+
2487
+ addrSeq := (n >> 0 ) & 0x1
2488
+ blkSize := (n >> 1 ) & 0x7ff
2489
+ blkNums := (n >> 12 ) & 0x1ff
2490
+ stride := (n >> 21 ) & 0xffff
2491
+
2492
+ if blkSize > 1024 {
2493
+ c .ctxt .Diag ("%v: block_size amount out of range[16, 1024]: %v\n " , p , blkSize )
2494
+ }
2495
+
2496
+ if blkNums > 256 {
2497
+ c .ctxt .Diag ("%v: block_nums amount out of range[1, 256]: %v\n " , p , blkSize )
2498
+ }
2499
+
2500
+ v := (uint64 (offs ) & 0xffff )
2501
+ v += addrSeq << 16
2502
+ v += ((blkSize / 16 ) - 1 ) << 20
2503
+ v += (blkNums - 1 ) << 32
2504
+ v += stride << 44
2505
+
2506
+ o1 = OP_IR (c .opir (ALU12IW ), uint32 (v >> 12 ), uint32 (REGTMP ))
2507
+ o2 = OP_12IRR (c .opirr (AOR ), uint32 (v ), uint32 (REGTMP ), uint32 (REGTMP ))
2508
+ o3 = OP_IR (c .opir (ALU32ID ), uint32 (v >> 32 ), uint32 (REGTMP ))
2509
+ o4 = OP_12IRR (c .opirr (ALU52ID ), uint32 (v >> 52 ), uint32 (REGTMP ), uint32 (REGTMP ))
2510
+ o5 = OP_5IRR (c .opirr (p .As ), uint32 (REGTMP ), uint32 (p .From .Reg ), uint32 (hint ))
2470
2511
2471
2512
case 49 :
2472
2513
if p .As == ANOOP {
0 commit comments