@@ -258,8 +258,10 @@ func MOVCONST(d int64, s int, rt int) uint32 {
258
258
}
259
259
260
260
const (
261
- LFROM = 1 << 0
262
- LTO = 1 << 1
261
+ // Optab.flag
262
+ LFROM = 1 << 0 // p.From uses constant pool
263
+ LTO = 1 << 1 // p.To uses constant pool
264
+ NOTUSETMP = 1 << 2 // p expands to multiple instructions, but does NOT use REGTMP
263
265
)
264
266
265
267
var optab = []Optab {
@@ -383,10 +385,10 @@ var optab = []Optab{
383
385
{AMOVD , C_MOVCON , C_NONE , C_NONE , C_REG , 32 , 4 , 0 , 0 , 0 },
384
386
{AMOVW , C_BITCON , C_NONE , C_NONE , C_REG , 32 , 4 , 0 , 0 , 0 },
385
387
{AMOVD , C_BITCON , C_NONE , C_NONE , C_REG , 32 , 4 , 0 , 0 , 0 },
386
- {AMOVW , C_MOVCON2 , C_NONE , C_NONE , C_REG , 12 , 8 , 0 , 0 , 0 },
387
- {AMOVD , C_MOVCON2 , C_NONE , C_NONE , C_REG , 12 , 8 , 0 , 0 , 0 },
388
- {AMOVD , C_MOVCON3 , C_NONE , C_NONE , C_REG , 12 , 12 , 0 , 0 , 0 },
389
- {AMOVD , C_VCON , C_NONE , C_NONE , C_REG , 12 , 16 , 0 , 0 , 0 },
388
+ {AMOVW , C_MOVCON2 , C_NONE , C_NONE , C_REG , 12 , 8 , 0 , NOTUSETMP , 0 },
389
+ {AMOVD , C_MOVCON2 , C_NONE , C_NONE , C_REG , 12 , 8 , 0 , NOTUSETMP , 0 },
390
+ {AMOVD , C_MOVCON3 , C_NONE , C_NONE , C_REG , 12 , 12 , 0 , NOTUSETMP , 0 },
391
+ {AMOVD , C_VCON , C_NONE , C_NONE , C_REG , 12 , 16 , 0 , NOTUSETMP , 0 },
390
392
391
393
{AMOVK , C_VCON , C_NONE , C_NONE , C_REG , 33 , 4 , 0 , 0 , 0 },
392
394
{AMOVD , C_AACON , C_NONE , C_NONE , C_REG , 4 , 4 , REGFROM , 0 , 0 },
@@ -420,15 +422,15 @@ var optab = []Optab{
420
422
{ALSL , C_REG , C_REG , C_NONE , C_REG , 9 , 4 , 0 , 0 , 0 },
421
423
{ASVC , C_VCON , C_NONE , C_NONE , C_NONE , 10 , 4 , 0 , 0 , 0 },
422
424
{ASVC , C_NONE , C_NONE , C_NONE , C_NONE , 10 , 4 , 0 , 0 , 0 },
423
- {ADWORD , C_NONE , C_NONE , C_NONE , C_VCON , 11 , 8 , 0 , 0 , 0 },
424
- {ADWORD , C_NONE , C_NONE , C_NONE , C_LEXT , 11 , 8 , 0 , 0 , 0 },
425
- {ADWORD , C_NONE , C_NONE , C_NONE , C_ADDR , 11 , 8 , 0 , 0 , 0 },
426
- {ADWORD , C_NONE , C_NONE , C_NONE , C_LACON , 11 , 8 , 0 , 0 , 0 },
425
+ {ADWORD , C_NONE , C_NONE , C_NONE , C_VCON , 11 , 8 , 0 , NOTUSETMP , 0 },
426
+ {ADWORD , C_NONE , C_NONE , C_NONE , C_LEXT , 11 , 8 , 0 , NOTUSETMP , 0 },
427
+ {ADWORD , C_NONE , C_NONE , C_NONE , C_ADDR , 11 , 8 , 0 , NOTUSETMP , 0 },
428
+ {ADWORD , C_NONE , C_NONE , C_NONE , C_LACON , 11 , 8 , 0 , NOTUSETMP , 0 },
427
429
{AWORD , C_NONE , C_NONE , C_NONE , C_LCON , 14 , 4 , 0 , 0 , 0 },
428
430
{AWORD , C_NONE , C_NONE , C_NONE , C_LEXT , 14 , 4 , 0 , 0 , 0 },
429
431
{AWORD , C_NONE , C_NONE , C_NONE , C_ADDR , 14 , 4 , 0 , 0 , 0 },
430
- {AMOVW , C_VCONADDR , C_NONE , C_NONE , C_REG , 68 , 8 , 0 , 0 , 0 },
431
- {AMOVD , C_VCONADDR , C_NONE , C_NONE , C_REG , 68 , 8 , 0 , 0 , 0 },
432
+ {AMOVW , C_VCONADDR , C_NONE , C_NONE , C_REG , 68 , 8 , 0 , NOTUSETMP , 0 },
433
+ {AMOVD , C_VCONADDR , C_NONE , C_NONE , C_REG , 68 , 8 , 0 , NOTUSETMP , 0 },
432
434
{AMOVB , C_REG , C_NONE , C_NONE , C_ADDR , 64 , 12 , 0 , 0 , 0 },
433
435
{AMOVBU , C_REG , C_NONE , C_NONE , C_ADDR , 64 , 12 , 0 , 0 , 0 },
434
436
{AMOVH , C_REG , C_NONE , C_NONE , C_ADDR , 64 , 12 , 0 , 0 , 0 },
@@ -1022,6 +1024,23 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
1022
1024
psz += 4
1023
1025
}
1024
1026
}
1027
+
1028
+ // Mark nonpreemptible instruction sequences.
1029
+ // We use REGTMP as a scratch register during call injection,
1030
+ // so instruction sequences that use REGTMP are unsafe to
1031
+ // preempt asynchronously.
1032
+ obj .MarkUnsafePoints (c .ctxt , c .cursym .Func .Text , c .newprog , c .isUnsafePoint )
1033
+ }
1034
+
1035
+ // Return whether p is an unsafe point.
1036
+ func (c * ctxt7 ) isUnsafePoint (p * obj.Prog ) bool {
1037
+ if p .From .Reg == REGTMP || p .To .Reg == REGTMP || p .Reg == REGTMP {
1038
+ return true
1039
+ }
1040
+ // Most of the multi-instruction sequence uses REGTMP, except
1041
+ // ones marked safe.
1042
+ o := c .oplook (p )
1043
+ return o .size > 4 && o .flag & NOTUSETMP == 0
1025
1044
}
1026
1045
1027
1046
/*
@@ -3069,6 +3088,8 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
3069
3088
}
3070
3089
3071
3090
case 12 : /* movT $vcon, reg */
3091
+ // NOTE: this case does not use REGTMP. If it ever does,
3092
+ // remove the NOTUSETMP flag in optab.
3072
3093
num := c .omovlconst (p .As , p , & p .From , int (p .To .Reg ), os [:])
3073
3094
if num == 0 {
3074
3095
c .ctxt .Diag ("invalid constant: %v" , p )
@@ -4017,6 +4038,8 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
4017
4038
o1 = c .opldpstp (p , o , v , uint32 (r ), uint32 (p .From .Reg ), uint32 (p .From .Offset ), 0 )
4018
4039
4019
4040
case 68 : /* movT $vconaddr(SB), reg -> adrp + add + reloc */
4041
+ // NOTE: this case does not use REGTMP. If it ever does,
4042
+ // remove the NOTUSETMP flag in optab.
4020
4043
if p .As == AMOVW {
4021
4044
c .ctxt .Diag ("invalid load of 32-bit address: %v" , p )
4022
4045
}
0 commit comments