#include "sys.h"
#include "picorv32.h"

#define GP_IS_ZERO 1

	// The code in this file is sensitive to alignment, so
	// don't use compressed instructions (there are very few anyway)
	.option norvc

	// NULL pointer guard area
	// This needs to be an explicitly allocated section or the binary
	// memory initialization file ends up broken.
	//
	// This also contains a pointer to the ROM area associated
	// with this image. For a non-primary image it is patched to
	// the preferred value.
	.section ".null","a"
	.globl _NULL
_NULL:
	.space 12
	.type	_NULL, @object
	.size	_NULL, . - _NULL

	.globl __rom_offset
__rom_offset:
	.long ROM_OFFSET
	.type	__rom_offset, @object
	.size	__rom_offset, . - __rom_offset

	// The linker will always assign this to _PC_RESET
	.section ".init.reset","ax"
	.globl _reset
_reset:
	rdtime s0		// Record timer at reset
	li sp,STACK_TOP		// Cheaper than using la sp,___stack_top
	j __start
	.type _reset, @function
	.size _reset, . - _reset

	.section ".init","ax"
	.globl __start
__start:
	not t0,zero
	maskirq zero,t0,zero
#if !GP_IS_ZERO
	.option push
	.option norelax		// Can't make gp references to set up gp...
	la gp, __global_pointer$
	.option pop
#else
	// Zero gp (linker will usually replace with the zero reg)
	li gp,0
#endif
	addqxi gp,gp,0		// Set gp for interrupt code too

	// Clear bss
	la a0,__BSS_START__
	la a1,__BSS_END__

.L_clear_bss_loop:
	sw zero,(a0)
	sw zero,4(a0)
	sw zero,8(a0)
	sw zero,12(a0)
	sw zero,16(a0)
	sw zero,20(a0)
	sw zero,24(a0)
	sw zero,28(a0)
	addi a0,a0,32
	bltu a0,a1,.L_clear_bss_loop

	sw s0, time_zero, t0
	j main
	.type __start, @function
	.size __start, . - __start

	.pushsection ".sbss","a"
	.balign 4
	.globl time_zero
time_zero:
	.space 4
	.type time_zero, @object
	.size time_zero, . - time_zero
	.popsection

	.section ".stack","aw",@nobits
	.balign 4
	.globl ___stack_bottom
___stack:
	.space STACK_SIZE
	.type ___stack, @object
	.size ___stack, STACK_SIZE

	.globl ___stack_top
___stack_top:
