// SPDX-License-Identifier: Apache-2.0
/*
 * Copyright 2001-2026 Richard Lesh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define iINT_MIN		1
#define iINT_MAX		2
#define iFLOAT_MIN		3
#define iFLOAT_LOWEST	4
#define iFLOAT_MAX		5
#define iNEGATIVE_INFINITY	6
#define iPOSITIVE_INFINITY	7
#define iNAN			8

#define	iCYCLES			10
#define	iCLOCK			11
#define	iSAVE			12
#define	iSAVE_FP		13
#define	iRESTORE		14
#define	iRESTORE_FP		15
#define iPrintCPUState	16

#define	iALLOC			20
#define	iREALLOC		21
#define	iFREE			22
#define iMEMMOVE		23
#define iMEMCLEAR		24
#define	iALLOC_COUNT	25
#define	iFREE_COUNT		26
#define iALLOC_SIZE		27
#define iFREE_SIZE		28
#define iWALK_HEAP		29
#define	iARGC			30
#define	iARGS			31
#define	iEXIT			32
#define iSYSTEM			33
#define	iGET_PID		34
#define iNEXT_PID		35
#define	iGET_NUM_CORES	36
#define	iFORK			37
#define	iWAIT			38
#define	iWAIT_PID		39
#define	iTHREAD			40
#define	iJOIN_THREAD	41
#define	iSLEEP			42
#define iWAKE_THREAD    43
#define iALLOC_SHARED	44

#define	TRUE	-1
#define	FALSE	0

#define HEAP_BLOCK_HEADER_SIZE 3 // Size of the heap block header in words

#def_macro	TO_BOOLEAN(x)
	test	${x}
	move	z, r0, FALSE, TRUE
#end_macro

#def_macro	TO_NOT_BOOLEAN(x)
	test	${x}
	move	z, r0, TRUE, FALSE
#end_macro

// Compares x and y using the operator op and returns TRUE or FALSE in r0
#def_macro	COMPARE(x, op, y)
	cmp		${x}, ${y}
	move	${op}, r0, TRUE, FALSE
#end_macro

// Compares if low op1 x op2 high and returns TRUE or FALSE in r0
#def_macro	COMPARE_RANGE(low, op1, x, op2, high)
	push	r1
	#macro COMPARE(${low}, ${op1}, ${x})
	move	r1, r0
	#macro COMPARE(${x}, ${op2}, ${high})
	and		r0, r1
	pop		r1
	test	r0
#end_macro

#def_macro	ALLOC(size)
	push	r1
	move	r1, ${size}
	int		iALLOC
	pop		r1
#end_macro

#def_macro	REALLOC(addr, size)
	save	r1,r2
	move	r2, ${size}
	move	r1, ${addr}
	int		iREALLOC
	restore	r1,r2
#end_macro

#def_macro	FREE_ELEMENT(a, offset)
	push	r1
	load	r1, ${a}[${offset}]
	int		iFREE
	pop		r1
#end_macro

#def_macro	FREE(a)
	push	r1
	move	r1, ${a}
	int		iFREE
	pop		r1
#end_macro

#def_macro	ALLOC_SHARED(size)
	push	r1
	move	r1, ${size}
	int		iALLOC_SHARED
	pop		r1
#end_macro

#def_macro	MEMMOVE(dest, src, size)
	save	r1,r3
	move	r1, ${dest}
	move	r2, ${src}
	move	r3, ${size}
	int		iMEMMOVE
	restore	r1,r3
#end_macro

#def_macro	MEMCLEAR(dest, size)
	save	r1,r2
	move	r1, ${dest}
	move	r2, ${size}
	int		iMEMCLEAR
	restore	r1,r2
#end_macro

#def_macro	SLEEP(ms)
	move	r1, ${ms}
	int		iSLEEP
#end_macro
