v := pcAlignPadLength(p.Pc, alignedValue)
offset := p.Pc
for ; v >= 4; v -= 4 {
- // NOP
- cursym.WriteBytes(ctxt, offset, []byte{0x13, 0, 0, 0})
+ // NOP (ADDI $0, X0, X0)
+ cursym.WriteBytes(ctxt, offset, []byte{0x13, 0x00, 0x00, 0x00})
offset += 4
}
+ if v == 2 {
+ // CNOP
+ cursym.WriteBytes(ctxt, offset, []byte{0x01, 0x00})
+ offset += 2
+ } else if v != 0 {
+ ctxt.Diag("bad PCALIGN pad length")
+ }
continue
}
ByteOrder: binary.LittleEndian,
PtrSize: 8,
RegSize: 8,
- MinLC: 4,
+ MinLC: 2,
Alignment: 8, // riscv unaligned loads work, but are really slow (trap + simulated by OS)
CanMergeLoads: false,
HasLR: true,
const (
_ArchFamily = RISCV64
_DefaultPhysPageSize = 4096
- _PCQuantum = 4
+ _PCQuantum = 2
_MinFrameSize = 8
_StackAlign = PtrSize
)
RET
// func goexit(neverCallThisFunction)
-// The top-most function running on a goroutine
-// returns to goexit+PCQuantum.
+// The top-most function running on a goroutine, returns to goexit+PCQuantum*2.
+// Note that the NOPs are written in a manner that will not be compressed,
+// since the offset must be known by the runtime.
TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
- MOV ZERO, ZERO // NOP
+ WORD $0x00000013 // NOP
JMP runtime·goexit1(SB) // does not return
// traceback from goexit1 must hit code range of goexit
- MOV ZERO, ZERO // NOP
-
+ WORD $0x00000013 // NOP
// This is called from .init_array and follows the platform, not the Go ABI.
TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
package runtime
-import "unsafe"
+import (
+ "unsafe"
+
+ "internal/abi"
+ "internal/runtime/sys"
+)
// adjust Gobuf as if it executed a call to fn with context ctxt
// and then did an immediate Gosave.
if buf.lr != 0 {
throw("invalid use of gostartcall")
}
- buf.lr = buf.pc
+ // Use double the PC quantum on riscv64, so that we retain
+ // four byte alignment and use non-compressed instructions.
+ buf.lr = abi.FuncPCABI0(goexit) + sys.PCQuantum*2
buf.pc = uintptr(fn)
buf.ctxt = ctxt
}