@@ -41,13 +41,11 @@ import (
41
41
"fmt"
42
42
)
43
43
44
- // resolvepseudoreg concretizes pseudo-registers in an Addr.
45
- func resolvepseudoreg (a * obj.Addr ) {
46
- if a .Type == obj .TYPE_MEM {
47
- switch a .Name {
48
- case obj .NAME_PARAM :
49
- a .Reg = REG_FP
50
- }
44
+ // stackOffset updates Addr offsets based on the current stack size.
45
+ func stackOffset (a * obj.Addr , stacksize int64 ) {
46
+ switch a .Name {
47
+ case obj .NAME_AUTO , obj .NAME_PARAM :
48
+ a .Offset += stacksize
51
49
}
52
50
}
53
51
@@ -108,11 +106,9 @@ func movtos(mnemonic obj.As) obj.As {
108
106
}
109
107
}
110
108
111
- // addrtoreg extracts the register from an addr , handling SB and SP .
109
+ // addrtoreg extracts the register from an Addr , handling special Addr.Names .
112
110
func addrtoreg (a obj.Addr ) int16 {
113
111
switch a .Name {
114
- case obj .NAME_EXTERN :
115
- return REG_SB
116
112
case obj .NAME_PARAM , obj .NAME_AUTO :
117
113
return REG_SP
118
114
}
@@ -164,11 +160,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
164
160
}
165
161
}
166
162
167
- // Concretize pseudo-registers.
168
- resolvepseudoreg (& p .From )
169
- resolvepseudoreg (p .From3 )
170
- resolvepseudoreg (& p .To )
171
-
172
163
// Do additional single-instruction rewriting.
173
164
switch p .As {
174
165
// Turn JMP into JAL ZERO or JALR ZERO.
@@ -272,10 +263,10 @@ func InvertBranch(i obj.As) obj.As {
272
263
}
273
264
}
274
265
275
- // preprocess generates prologue and epilogue code and computes PC-relative
276
- // branch and jump offsets.
266
+ // preprocess generates prologue and epilogue code, computes PC-relative branch
267
+ // and jump offsets, and resolves psuedo-registers .
277
268
//
278
- // preprocess is called once for each linker symbol.
269
+ // preprocess is called once per linker symbol.
279
270
//
280
271
// When preprocess finishes, all instructions in the symbol are either
281
272
// concrete, real RISC-V instructions or directive pseudo-ops like TEXT,
@@ -287,7 +278,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
287
278
ctxt .Diag ("preprocess: found symbol that does not start with TEXT directive" )
288
279
return
289
280
}
281
+
290
282
stacksize := text .To .Offset
283
+
284
+ cursym .Args = text .To .Val .(int32 )
285
+ cursym .Locals = int32 (stacksize )
286
+
291
287
// Insert stack adjustment if necessary.
292
288
if stacksize != 0 {
293
289
spadj := obj .Appendp (ctxt , text )
@@ -300,11 +296,25 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
300
296
spadj .Spadj = int32 (- stacksize )
301
297
}
302
298
299
+ // Update stack-based offsets.
300
+ for p := cursym .Text ; p != nil ; p = p .Link {
301
+ stackOffset (& p .From , stacksize )
302
+ if p .From3 != nil {
303
+ stackOffset (p .From3 , stacksize )
304
+ }
305
+ stackOffset (& p .To , stacksize )
306
+
307
+ // TODO: update stacksize when instructions that modify SP are
308
+ // found, or disallow it entirely.
309
+ }
310
+
303
311
// Additional instruction rewriting.
304
312
for p := cursym .Text ; p != nil ; p = p .Link {
305
313
switch p .As {
306
314
307
- // Rewrite MOV.
315
+ // Rewrite MOV. This couldn't be done in progedit, as SP
316
+ // offsets needed to be applied before we split up some of the
317
+ // Addrs.
308
318
case AMOV , AMOVB , AMOVH , AMOVW , AMOVBU , AMOVHU , AMOVWU :
309
319
switch p .From .Type {
310
320
case obj .TYPE_MEM : // MOV c(Rs), Rd -> L $c, Rs, Rd
@@ -404,7 +414,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
404
414
p .From .Type = obj .TYPE_CONST
405
415
switch p .From .Name {
406
416
case obj .NAME_EXTERN :
407
- p .From3 .Reg = REG_SB
417
+ // Doesn't matter, we'll add a
418
+ // relocation later.
408
419
case obj .NAME_PARAM , obj .NAME_AUTO :
409
420
p .From3 .Reg = REG_SP
410
421
default :
0 commit comments