/* inst-set-test.S. Instruction set test library for Or1ksim
|
/* inst-set-test.S. Instruction set test library for Or1ksim
|
*
|
*
|
* Copyright (C) 1999-2006 OpenCores
|
* Copyright (C) 1999-2006 OpenCores
|
* Copyright (C) 2010 Embecosm Limited
|
* Copyright (C) 2010 Embecosm Limited
|
*
|
*
|
* Contributors various OpenCores participants
|
* Contributors various OpenCores participants
|
* Contributor Jeremy Bennett
|
* Contributor Jeremy Bennett
|
*
|
*
|
* This file is part of OpenRISC 1000 Architectural Simulator.
|
* This file is part of OpenRISC 1000 Architectural Simulator.
|
*
|
*
|
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
* under the terms of the GNU General Public License as published by the Free
|
* under the terms of the GNU General Public License as published by the Free
|
* Software Foundation; either version 3 of the License, or (at your option)
|
* Software Foundation; either version 3 of the License, or (at your option)
|
* any later version.
|
* any later version.
|
*
|
*
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
* more details.
|
* more details.
|
*
|
*
|
* You should have received a copy of the GNU General Public License along
|
* You should have received a copy of the GNU General Public License along
|
* with this program. If not, see .
|
* with this program. If not, see .
|
*/
|
*/
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Coding conventions
|
* Coding conventions
|
*
|
*
|
* A simple rising stack is provided starting at _stack and pointed to by
|
* A simple rising stack is provided starting at _stack and pointed to by
|
* r1. r1 points to the next free word. Only 32-bit registers may be pushed
|
* r1. r1 points to the next free word. Only 32-bit registers may be pushed
|
* onto the stack.
|
* onto the stack.
|
*
|
*
|
* Local labels up to 49 are reserved for macros. Each is used only once in
|
* Local labels up to 49 are reserved for macros. Each is used only once in
|
* all macros. You can get in a serious mess if you get local label clashing
|
* all macros. You can get in a serious mess if you get local label clashing
|
* in macros.
|
* in macros.
|
*
|
*
|
* Arguments to functions are passed in r3 through r8.
|
* Arguments to functions are passed in r3 through r8.
|
* r9 is the link (return address)
|
* r9 is the link (return address)
|
* r11 is for returning results
|
* r11 is for returning results
|
*
|
*
|
* All registers apart from r2, r9 and r11 are preserved across function calls.
|
* All registers apart from r2, r9 and r11 are preserved across function calls.
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* This library contains the stack implementation and reset sequence and a set
|
* This library contains the stack implementation and reset sequence and a set
|
* of library functions.
|
* of library functions.
|
*
|
*
|
* The functions provided here provide simple utilities that are useful when
|
* The functions provided here provide simple utilities that are useful when
|
* writing tests in assembler.
|
* writing tests in assembler.
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
|
|
#include "inst-set-test.h"
|
#include "inst-set-test.h"
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Simple stack, will be pointed to by r1, which is the next empty slot
|
* Simple stack, will be pointed to by r1, which is the next empty slot
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.section .stack
|
.section .stack
|
.balign 4
|
.balign 4
|
.global _stack
|
.global _stack
|
_stack:
|
_stack:
|
.space 0x1000,0x0
|
.space 0x1000,0x0
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Exception handling
|
* Exception handling
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.section .boot-text
|
.section .boot-text
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Reset exception
|
* Reset exception
|
*
|
*
|
* Set up the stack and jump to _start
|
* Set up the stack and jump to _start
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.org 0x100
|
.org 0x100
|
.global _reset
|
.global _reset
|
_reset:
|
_reset:
|
l.movhi r1,hi(_stack) /* Set up the stack */
|
l.movhi r1,hi(_stack) /* Set up the stack */
|
l.ori r1,r1,lo(_stack)
|
l.ori r1,r1,lo(_stack)
|
|
|
l.j _start /* Jump to the start of code */
|
l.j _start /* Jump to the start of code */
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Alignment exception
|
* Alignment exception
|
*
|
*
|
* Don't be tempted to use the LOAD_STR macro here, it will dump us back into
|
* Don't be tempted to use the LOAD_STR macro here, it will dump us back into
|
* text section.
|
* text section.
|
*
|
*
|
* The handling is a bit dubious at present. We just patch the instruction and
|
* The handling is a bit dubious at present. We just patch the instruction and
|
* restart. This will go wrong in branch delay slots. Really we need to single
|
* restart. This will go wrong in branch delay slots. Really we need to single
|
* step past and then continue.
|
* step past and then continue.
|
*
|
*
|
* Print a message identifying the exception type.
|
* Print a message identifying the exception type.
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.section .rodata
|
.section .rodata
|
50: .string " ALIGNMENT exception\n"
|
50: .string " ALIGNMENT exception\n"
|
|
|
.section .boot-text
|
.section .boot-text
|
.org 0x600
|
.org 0x600
|
.global _align
|
.global _align
|
_align:
|
_align:
|
/* Report exception */
|
/* Report exception */
|
LOAD_CONST (r3, 50b)
|
LOAD_CONST (r3, 50b)
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
/* Patch with l.nop */
|
/* Patch with l.nop */
|
l.mfspr r2,r0,SPR_EPCR_BASE /* Addr of problem instr */
|
l.mfspr r2,r0,SPR_EPCR_BASE /* Addr of problem instr */
|
LOAD_CONST (r3, 0x15000000) /* l.nop */
|
LOAD_CONST (r3, 0x15000000) /* l.nop */
|
l.sw 0(r2),r3
|
l.sw 0(r2),r3
|
|
|
/* All done */
|
/* All done */
|
l.rfe
|
l.rfe
|
_align_end:
|
_align_end:
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Illegal instruction exception
|
* Illegal instruction exception
|
*
|
*
|
* Don't be tempted to use the LOAD_STR macro here, it will dump us back into
|
* Don't be tempted to use the LOAD_STR macro here, it will dump us back into
|
* text section.
|
* text section.
|
*
|
*
|
* The handling is a bit dubious at present. We just patch the instruction and
|
* The handling is a bit dubious at present. We just patch the instruction and
|
* restart. This will go wrong in branch delay slots. Really we need to single
|
* restart. This will go wrong in branch delay slots. Really we need to single
|
* step past and then continue.
|
* step past and then continue.
|
*
|
*
|
* Print a message identifying the exception type.
|
* Print a message identifying the exception type.
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.section .rodata
|
.section .rodata
|
51: .string " ILLEGAL INSTRUCTION exception\n"
|
51: .string " ILLEGAL INSTRUCTION exception\n"
|
|
|
.section .boot-text
|
.section .boot-text
|
.org 0x700
|
.org 0x700
|
.global _illegal
|
.global _illegal
|
_illegal:
|
_illegal:
|
/* Report exception */
|
/* Report exception */
|
LOAD_CONST (r3, 51b)
|
LOAD_CONST (r3, 51b)
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
/* Patch with l.nop */
|
/* Patch with l.nop */
|
l.mfspr r2,r0,SPR_EPCR_BASE /* Addr of problem instr */
|
l.mfspr r2,r0,SPR_EPCR_BASE /* Addr of problem instr */
|
LOAD_CONST (r3, 0x15000000) /* l.nop */
|
LOAD_CONST (r3, 0x15000000) /* l.nop */
|
l.sw 0(r2),r3
|
l.sw 0(r2),r3
|
|
|
/* All done */
|
/* All done */
|
l.rfe
|
l.rfe
|
_illegal_end:
|
_illegal_end:
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Range exception
|
* Range exception
|
*
|
*
|
* Don't be tempted to use the LOAD_STR macro here, it will dump us back into
|
* Don't be tempted to use the LOAD_STR macro here, it will dump us back into
|
* text section.
|
* text section.
|
*
|
*
|
* The handling is a bit dubious at present. We just patch the instruction and
|
* The handling is a bit dubious at present. We just patch the instruction and
|
* restart. This will go wrong in branch delay slots. Really we need to single
|
* restart. This will go wrong in branch delay slots. Really we need to single
|
* step past and then continue.
|
* step past and then continue.
|
*
|
*
|
* Print a message identifying the exception type.
|
* Print a message identifying the exception type.
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.section .rodata
|
.section .rodata
|
52: .string " RANGE exception\n"
|
52: .string " RANGE exception\n"
|
|
|
.section .boot-text
|
.section .boot-text
|
.org 0xb00
|
.org 0xb00
|
.global _range
|
.global _range
|
_range:
|
_range:
|
/* Report exception */
|
/* Report exception */
|
LOAD_CONST (r3, 52b)
|
LOAD_CONST (r3, 52b)
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
/* Patch with l.nop */
|
/* Patch with l.nop */
|
l.mfspr r2,r0,SPR_EPCR_BASE /* Addr of problem instr */
|
l.mfspr r2,r0,SPR_EPCR_BASE /* Addr of problem instr */
|
LOAD_CONST (r3, 0x15000000) /* l.nop */
|
LOAD_CONST (r3, 0x15000000) /* l.nop */
|
l.sw 0(r2),r3
|
l.sw 0(r2),r3
|
|
|
/* All done */
|
/* All done */
|
l.rfe
|
l.rfe
|
_range_end:
|
_range_end:
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* End of exception vectors
|
* End of exception vectors
|
*
|
*
|
* Guarantee the exception vector space does not have general purpose code
|
* Guarantee the exception vector space does not have general purpose code
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.org 0xffc
|
.org 0xffc
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* All subroutines are in the text section.
|
* All subroutines are in the text section.
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.section .text
|
.section .text
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out a string
|
* Subroutine to print out a string
|
*
|
*
|
* The string is followed by a newline
|
* The string is followed by a newline
|
*
|
*
|
* Parameters:
|
* Parameters:
|
* r3 Pointer to the string to print
|
* r3 Pointer to the string to print
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.global _puts
|
.global _puts
|
_puts:
|
_puts:
|
PUSH (r3)
|
PUSH (r3)
|
l.add r2,r0,r3 /* Copy the string pointer */
|
l.add r2,r0,r3 /* Copy the string pointer */
|
|
|
/* Loop getting and printing each char until end of string */
|
/* Loop getting and printing each char until end of string */
|
60: l.lbz r3,0(r2)
|
60: l.lbz r3,0(r2)
|
l.sfeq r3,r0 /* NULL termination? */
|
l.sfeq r3,r0 /* NULL termination? */
|
l.bf 61f
|
l.bf 61f
|
|
|
l.addi r2,r2,1 /* Delay slot, move to next char */
|
l.addi r2,r2,1 /* Delay slot, move to next char */
|
l.j 60b /* Repeat */
|
l.j 60b /* Repeat */
|
l.nop NOP_PUTC /* Delay slot */
|
l.nop NOP_PUTC /* Delay slot */
|
|
|
61: POP (r3)
|
61: POP (r3)
|
l.jr r9 /* Return */
|
l.jr r9 /* Return */
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out a register in hex
|
* Subroutine to print out a register in hex
|
*
|
*
|
* Parameters:
|
* Parameters:
|
* r3 The value to print
|
* r3 The value to print
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.section .rodata
|
.section .rodata
|
62: .string "0123456789abcdef"
|
62: .string "0123456789abcdef"
|
.section .text
|
.section .text
|
|
|
.global _puth
|
.global _puth
|
_puth:
|
_puth:
|
PUSH (r3)
|
PUSH (r3)
|
PUSH (r4)
|
PUSH (r4)
|
|
|
l.add r2,r0,r3 /* Copy the value pointer */
|
l.add r2,r0,r3 /* Copy the value pointer */
|
LOAD_CONST (r4,62b) /* Ptr to digit chars */
|
LOAD_CONST (r4,62b) /* Ptr to digit chars */
|
|
|
l.srli r3,r2,28 /* Print each digit in turn. */
|
l.srli r3,r2,28 /* Print each digit in turn. */
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.srli r3,r2,24
|
l.srli r3,r2,24
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.srli r3,r2,20
|
l.srli r3,r2,20
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.srli r3,r2,16
|
l.srli r3,r2,16
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.srli r3,r2,12
|
l.srli r3,r2,12
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.srli r3,r2,8
|
l.srli r3,r2,8
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.srli r3,r2,4
|
l.srli r3,r2,4
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.andi r3,r2,0xf
|
l.andi r3,r2,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
POP (r4) /* Return */
|
POP (r4) /* Return */
|
POP (r3)
|
POP (r3)
|
l.jr r9
|
l.jr r9
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out the lower half of a register in hex
|
* Subroutine to print out the lower half of a register in hex
|
*
|
*
|
* Parameters:
|
* Parameters:
|
* r3 The value to print
|
* r3 The value to print
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.section .rodata
|
.section .rodata
|
63: .string "0123456789abcdef"
|
63: .string "0123456789abcdef"
|
.section .text
|
.section .text
|
|
|
.global _puthh
|
.global _puthh
|
_puthh:
|
_puthh:
|
PUSH (r3)
|
PUSH (r3)
|
PUSH (r4)
|
PUSH (r4)
|
|
|
l.add r2,r0,r3 /* Copy the value pointer */
|
l.add r2,r0,r3 /* Copy the value pointer */
|
LOAD_CONST (r4,63b) /* Ptr to digit chars */
|
LOAD_CONST (r4,63b) /* Ptr to digit chars */
|
|
|
l.srli r3,r2,12 /* Print each digit in turn. */
|
l.srli r3,r2,12 /* Print each digit in turn. */
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.srli r3,r2,8
|
l.srli r3,r2,8
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.srli r3,r2,4
|
l.srli r3,r2,4
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.andi r3,r2,0xf
|
l.andi r3,r2,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
POP (r4) /* Return */
|
POP (r4) /* Return */
|
POP (r3)
|
POP (r3)
|
l.jr r9
|
l.jr r9
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out the lowest byte of a register in hex
|
* Subroutine to print out the lowest byte of a register in hex
|
*
|
*
|
* Parameters:
|
* Parameters:
|
* r3 The value to print
|
* r3 The value to print
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.section .rodata
|
.section .rodata
|
63: .string "0123456789abcdef"
|
63: .string "0123456789abcdef"
|
.section .text
|
.section .text
|
|
|
.global _puthq
|
.global _puthq
|
_puthq:
|
_puthq:
|
PUSH (r3)
|
PUSH (r3)
|
PUSH (r4)
|
PUSH (r4)
|
|
|
l.add r2,r0,r3 /* Copy the value pointer */
|
l.add r2,r0,r3 /* Copy the value pointer */
|
LOAD_CONST (r4,63b) /* Ptr to digit chars */
|
LOAD_CONST (r4,63b) /* Ptr to digit chars */
|
|
|
l.srli r3,r2,4 /* Print each digit in turn. */
|
l.srli r3,r2,4 /* Print each digit in turn. */
|
l.andi r3,r3,0xf
|
l.andi r3,r3,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
l.andi r3,r2,0xf
|
l.andi r3,r2,0xf
|
l.add r3,r4,r3
|
l.add r3,r4,r3
|
l.lbz r3,0(r3)
|
l.lbz r3,0(r3)
|
l.nop NOP_PUTC
|
l.nop NOP_PUTC
|
|
|
POP (r4) /* Return */
|
POP (r4) /* Return */
|
POP (r3)
|
POP (r3)
|
l.jr r9
|
l.jr r9
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out a test name prompt
|
* Subroutine to print out a test name prompt
|
*
|
*
|
* The string is preceded by two spaces
|
* The string is preceded by two spaces
|
*
|
*
|
* Parameters:
|
* Parameters:
|
* r3 Pointer to the test name to print
|
* r3 Pointer to the test name to print
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.global _ptest
|
.global _ptest
|
_ptest:
|
_ptest:
|
PUSH (r9) /* Save the return address */
|
PUSH (r9) /* Save the return address */
|
PUSH (r3) /* Save the test name for later */
|
PUSH (r3) /* Save the test name for later */
|
|
|
LOAD_STR (r3, " ") /* Prefix */
|
LOAD_STR (r3, " ") /* Prefix */
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
POP(r3) /* Test name */
|
POP(r3) /* Test name */
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
POP (r9)
|
POP (r9)
|
l.jr r9
|
l.jr r9
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out "OK"
|
* Subroutine to print out "OK"
|
*
|
*
|
* The string is followed by a newline
|
* The string is followed by a newline
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.global _pok
|
.global _pok
|
_pok:
|
_pok:
|
PUSH (r9) /* Save the return address */
|
PUSH (r9) /* Save the return address */
|
PUSH (r3)
|
PUSH (r3)
|
|
|
LOAD_STR (r3, "OK\n")
|
LOAD_STR (r3, "OK\n")
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
POP (r3)
|
POP (r3)
|
POP (r9)
|
POP (r9)
|
l.jr r9
|
l.jr r9
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out "Failed"
|
* Subroutine to print out "Failed"
|
*
|
*
|
* The string is followed by a ": ", which will then allow a report
|
* The string is followed by a ": ", which will then allow a report
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.global _pfail
|
.global _pfail
|
_pfail:
|
_pfail:
|
PUSH (r9) /* Save the return address */
|
PUSH (r9) /* Save the return address */
|
PUSH (r3)
|
PUSH (r3)
|
|
|
LOAD_STR (r3, "Failed: ")
|
LOAD_STR (r3, "Failed: ")
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
POP (r3)
|
POP (r3)
|
POP (r9)
|
POP (r9)
|
l.jr r9
|
l.jr r9
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out "TRUE"
|
* Subroutine to print out "TRUE"
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.global _ptrue
|
.global _ptrue
|
_ptrue:
|
_ptrue:
|
PUSH (r9) /* Save the return address */
|
PUSH (r9) /* Save the return address */
|
PUSH (r3)
|
PUSH (r3)
|
|
|
LOAD_STR (r3, "TRUE")
|
LOAD_STR (r3, "TRUE")
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
POP (r3)
|
POP (r3)
|
POP (r9)
|
POP (r9)
|
l.jr r9
|
l.jr r9
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out "FALSE"
|
* Subroutine to print out "FALSE"
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.global _pfalse
|
.global _pfalse
|
_pfalse:
|
_pfalse:
|
PUSH (r9) /* Save the return address */
|
PUSH (r9) /* Save the return address */
|
PUSH (r3)
|
PUSH (r3)
|
|
|
LOAD_STR (r3, "FALSE")
|
LOAD_STR (r3, "FALSE")
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
POP (r3)
|
POP (r3)
|
POP (r9)
|
POP (r9)
|
l.jr r9
|
l.jr r9
|
l.nop
|
l.nop
|
|
|
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
* Subroutine to print out "unexpected"
|
* Subroutine to print out "unexpected"
|
*
|
*
|
* Preceded by a space and followed by a newline
|
* Preceded by a space and followed by a newline
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
.global _punexpected
|
.global _punexpected
|
_punexpected:
|
_punexpected:
|
PUSH (r9) /* Save the return address */
|
PUSH (r9) /* Save the return address */
|
PUSH (r3)
|
PUSH (r3)
|
|
|
LOAD_STR (r3, " unexpected\n")
|
LOAD_STR (r3, " unexpected\n")
|
l.jal _puts
|
l.jal _puts
|
l.nop
|
l.nop
|
|
|
POP (r3)
|
POP (r3)
|
POP (r9)
|
POP (r9)
|
l.jr r9
|
l.jr r9
|
l.nop
|
l.nop
|
|
|