Files
retrobsd/src/libicache/icaches.s
2014-04-09 14:27:18 +01:00

286 lines
12 KiB
ArmAsm

# /*
# Copyright (c) 2013, Alexey Frunze
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of the FreeBSD Project.
# */
#
# /*****************************************************************************/
# /* */
# /* MIPS icache */
# /* */
# /*****************************************************************************/
.text
.extern _gp
.extern _icRegs_
.extern _icHostRegs_
.extern _icmain_
.globl _icstart_
.type _icstart_, @function
_icstart_:
la $28, _gp
subu $29, $29, 1024 # allocate 1K of stack for us
sw $29, _icRegs_ + 4*29 # leave the rest to the program
addu $29, $29, 1024 - 16
j _icmain_
.globl _icDoSysCall_
.type _icDoSysCall_, @function
_icDoSysCall_:
sw $4, $_icsyscall_ # patch the syscall instruction
# We need to write back the data cache and invalidate the instruction
# cache for the location of the modified instruction before we can
# actually execute it
la $4, $_icsyscall_
synci 0($4) # does nothing on MIPS32 M4K since it has no caches
# sw $1, _icHostRegs_ + 4*1 # ar
# lw $1, _icRegs_ + 4*1 #
# sw $2, _icHostRegs_ + 4*2 # v0
lw $2, _icRegs_ + 4*2 #
# sw $3, _icHostRegs_ + 4*3 # v1
lw $3, _icRegs_ + 4*3 #
# sw $4, _icHostRegs_ + 4*4 # a0
lw $4, _icRegs_ + 4*4 #
# sw $5, _icHostRegs_ + 4*5 # a1
lw $5, _icRegs_ + 4*5 #
# sw $6, _icHostRegs_ + 4*6 # a2
lw $6, _icRegs_ + 4*6 #
# sw $7, _icHostRegs_ + 4*7 # a3
lw $7, _icRegs_ + 4*7 #
# sw $8, _icHostRegs_ + 4*8 # t0
lw $8, _icRegs_ + 4*8 #
# sw $9, _icHostRegs_ + 4*9 # t1
lw $9, _icRegs_ + 4*9 #
# sw $10, _icHostRegs_ + 4*10 # t2
lw $10, _icRegs_ + 4*10 #
# sw $11, _icHostRegs_ + 4*11 # t3
lw $11, _icRegs_ + 4*11 #
# sw $12, _icHostRegs_ + 4*12 # t4
lw $12, _icRegs_ + 4*12 #
# sw $13, _icHostRegs_ + 4*13 # t5
lw $13, _icRegs_ + 4*13 #
# sw $14, _icHostRegs_ + 4*14 # t6
lw $14, _icRegs_ + 4*14 #
# sw $15, _icHostRegs_ + 4*15 # t7
lw $15, _icRegs_ + 4*15 #
sw $16, _icHostRegs_ + 4*16
lw $16, _icRegs_ + 4*16
sw $17, _icHostRegs_ + 4*17
lw $17, _icRegs_ + 4*17
sw $18, _icHostRegs_ + 4*18
lw $18, _icRegs_ + 4*18
sw $19, _icHostRegs_ + 4*19
lw $19, _icRegs_ + 4*19
sw $20, _icHostRegs_ + 4*20
lw $20, _icRegs_ + 4*20
sw $21, _icHostRegs_ + 4*21
lw $21, _icRegs_ + 4*21
sw $22, _icHostRegs_ + 4*22
lw $22, _icRegs_ + 4*22
sw $23, _icHostRegs_ + 4*23
lw $23, _icRegs_ + 4*23
# sw $24, _icHostRegs_ + 4*24 # t8
lw $24, _icRegs_ + 4*24 #
# sw $25, _icHostRegs_ + 4*25 # t9
lw $25, _icRegs_ + 4*25 #
# sw $26, _icHostRegs_ + 4*26 # k0
# lw $26, _icRegs_ + 4*26 #
# sw $27, _icHostRegs_ + 4*27 # k1
# lw $27, _icRegs_ + 4*27 #
sw $28, _icHostRegs_ + 4*28 # gp
lw $28, _icRegs_ + 4*28 #
sw $29, _icHostRegs_ + 4*29 # sp
# lw $29, _icRegs_ + 4*29 #
# Make sure sp is updated "atomically" and not part by part
.set noat
lw $1, _icRegs_ + 4*29 #
move $29, $1 #
.set at
sw $30, _icHostRegs_ + 4*30
lw $30, _icRegs_ + 4*30
# sw $31, _icHostRegs_ + 4*31 # ra
# lw $31, _icRegs_ + 4*31 # ra
$_icsyscall_:
# This instruction gets patched, so it can have
# the requested system call number embedded in it
syscall
# RetroBSD may advance PC on returning from a syscall handler,
# skipping 2 instructions that follow the syscall instruction.
# Those 2 instructions typically set C's errno variable and
# are either executed on error or skipped on success.
# Account for this peculiarity.
j $_icsyscall_error_
nop
$_icsyscall_success_:
# sw $1, _icRegs_ + 4*1 # ar
# lw $1, _icHostRegs_ + 4*1 #
sw $2, _icRegs_ + 4*2 # v0
# lw $2, _icHostRegs_ + 4*2 #
sw $3, _icRegs_ + 4*3 # v1
# lw $3, _icHostRegs_ + 4*3 #
sw $4, _icRegs_ + 4*4 # a0
# lw $4, _icHostRegs_ + 4*4 #
sw $5, _icRegs_ + 4*5 # a1
# lw $5, _icHostRegs_ + 4*5 #
sw $6, _icRegs_ + 4*6 # a2
# lw $6, _icHostRegs_ + 4*6 #
sw $7, _icRegs_ + 4*7 # a3
# lw $7, _icHostRegs_ + 4*7 #
sw $8, _icRegs_ + 4*8 # t0
# lw $8, _icHostRegs_ + 4*8 #
sw $9, _icRegs_ + 4*9 # t1
# lw $9, _icHostRegs_ + 4*9 #
sw $10, _icRegs_ + 4*10 # t2
# lw $10, _icHostRegs_ + 4*10 #
sw $11, _icRegs_ + 4*11 # t3
# lw $11, _icHostRegs_ + 4*11 #
sw $12, _icRegs_ + 4*12 # t4
# lw $12, _icHostRegs_ + 4*12 #
sw $13, _icRegs_ + 4*13 # t5
# lw $13, _icHostRegs_ + 4*13 #
sw $14, _icRegs_ + 4*14 # t6
# lw $14, _icHostRegs_ + 4*14 #
sw $15, _icRegs_ + 4*15 # t7
# lw $15, _icHostRegs_ + 4*15 #
sw $16, _icRegs_ + 4*16
lw $16, _icHostRegs_ + 4*16
sw $17, _icRegs_ + 4*17
lw $17, _icHostRegs_ + 4*17
sw $18, _icRegs_ + 4*18
lw $18, _icHostRegs_ + 4*18
sw $19, _icRegs_ + 4*19
lw $19, _icHostRegs_ + 4*19
sw $20, _icRegs_ + 4*20
lw $20, _icHostRegs_ + 4*20
sw $21, _icRegs_ + 4*21
lw $21, _icHostRegs_ + 4*21
sw $22, _icRegs_ + 4*22
lw $22, _icHostRegs_ + 4*22
sw $23, _icRegs_ + 4*23
lw $23, _icHostRegs_ + 4*23
sw $24, _icRegs_ + 4*24 # t8
# lw $24, _icHostRegs_ + 4*24 #
sw $25, _icRegs_ + 4*25 # t9
# lw $25, _icHostRegs_ + 4*25 #
# sw $26, _icRegs_ + 4*26 # k0
# lw $26, _icHostRegs_ + 4*26 #
# sw $27, _icRegs_ + 4*27 # k1
# lw $27, _icHostRegs_ + 4*27 #
sw $28, _icRegs_ + 4*28 # gp
lw $28, _icHostRegs_ + 4*28 #
sw $29, _icRegs_ + 4*29 # sp
# lw $29, _icHostRegs_ + 4*29 #
# Make sure sp is updated "atomically" and not part by part
.set noat
lw $1, _icHostRegs_ + 4*29 #
move $29, $1
.set at
sw $30, _icRegs_ + 4*30
lw $30, _icHostRegs_ + 4*30
# sw $31, _icRegs_ + 4*31 # ra
# lw $31, _icHostRegs_ + 4*31 #
li $2, 2 # success, 2 instructions skipped
j $31
$_icsyscall_error_:
# sw $1, _icRegs_ + 4*1 # ar
# lw $1, _icHostRegs_ + 4*1 #
sw $2, _icRegs_ + 4*2 # v0
# lw $2, _icHostRegs_ + 4*2 #
sw $3, _icRegs_ + 4*3 # v1
# lw $3, _icHostRegs_ + 4*3 #
sw $4, _icRegs_ + 4*4 # a0
# lw $4, _icHostRegs_ + 4*4 #
sw $5, _icRegs_ + 4*5 # a1
# lw $5, _icHostRegs_ + 4*5 #
sw $6, _icRegs_ + 4*6 # a2
# lw $6, _icHostRegs_ + 4*6 #
sw $7, _icRegs_ + 4*7 # a3
# lw $7, _icHostRegs_ + 4*7 #
sw $8, _icRegs_ + 4*8 # t0
# lw $8, _icHostRegs_ + 4*8 #
sw $9, _icRegs_ + 4*9 # t1
# lw $9, _icHostRegs_ + 4*9 #
sw $10, _icRegs_ + 4*10 # t2
# lw $10, _icHostRegs_ + 4*10 #
sw $11, _icRegs_ + 4*11 # t3
# lw $11, _icHostRegs_ + 4*11 #
sw $12, _icRegs_ + 4*12 # t4
# lw $12, _icHostRegs_ + 4*12 #
sw $13, _icRegs_ + 4*13 # t5
# lw $13, _icHostRegs_ + 4*13 #
sw $14, _icRegs_ + 4*14 # t6
# lw $14, _icHostRegs_ + 4*14 #
sw $15, _icRegs_ + 4*15 # t7
# lw $15, _icHostRegs_ + 4*15 #
sw $16, _icRegs_ + 4*16
lw $16, _icHostRegs_ + 4*16
sw $17, _icRegs_ + 4*17
lw $17, _icHostRegs_ + 4*17
sw $18, _icRegs_ + 4*18
lw $18, _icHostRegs_ + 4*18
sw $19, _icRegs_ + 4*19
lw $19, _icHostRegs_ + 4*19
sw $20, _icRegs_ + 4*20
lw $20, _icHostRegs_ + 4*20
sw $21, _icRegs_ + 4*21
lw $21, _icHostRegs_ + 4*21
sw $22, _icRegs_ + 4*22
lw $22, _icHostRegs_ + 4*22
sw $23, _icRegs_ + 4*23
lw $23, _icHostRegs_ + 4*23
sw $24, _icRegs_ + 4*24 # t8
# lw $24, _icHostRegs_ + 4*24 #
sw $25, _icRegs_ + 4*25 # t9
# lw $25, _icHostRegs_ + 4*25 #
# sw $26, _icRegs_ + 4*26 # k0
# lw $26, _icHostRegs_ + 4*26 #
# sw $27, _icRegs_ + 4*27 # k1
# lw $27, _icHostRegs_ + 4*27 #
sw $28, _icRegs_ + 4*28 # gp
lw $28, _icHostRegs_ + 4*28 #
sw $29, _icRegs_ + 4*29 # sp
# lw $29, _icHostRegs_ + 4*29 #
# Make sure sp is updated "atomically" and not part by part
.set noat
lw $1, _icHostRegs_ + 4*29 #
move $29, $1 #
.set at
sw $30, _icRegs_ + 4*30
lw $30, _icHostRegs_ + 4*30
# sw $31, _icRegs_ + 4*31 # ra
# lw $31, _icHostRegs_ + 4*31 #
li $2, 0 # failure, 0 instructions skipped
j $31