313 lines
10 KiB
ArmAsm
313 lines
10 KiB
ArmAsm
// TITLE("Unaligned Branch Tests")
|
||
//++
|
||
//
|
||
// Copyright (c) 1991 Microsoft Corporation
|
||
//
|
||
// Module Name:
|
||
//
|
||
// alignx.s
|
||
//
|
||
// Abstract:
|
||
//
|
||
// This module implements the unaligned branch tests.
|
||
//
|
||
// Author:
|
||
//
|
||
// David N. Cutler (davec) 27-Feb-1991
|
||
//
|
||
// Environment:
|
||
//
|
||
// User mode only.
|
||
//
|
||
// Revision History:
|
||
//
|
||
//--
|
||
|
||
#include "ksmips.h"
|
||
|
||
SBTTL("Unaligned BEQ/BNE/BC1F/BC1T Branch Tests")
|
||
//++
|
||
//
|
||
// Routine Description:
|
||
//
|
||
// The following routines implement beq/bne/bc1f/bc1t tests with an unaligned
|
||
// load word instruction in the delay slot.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// a0 - Supplies first operand for branch test.
|
||
// a1 - Supplies second operate for branch test.
|
||
// a2 - Supplies a pointer to an unaligned word.
|
||
// a3 - Supplies a pointer to an aligned word that receives the result
|
||
// of the unaligned load.
|
||
//
|
||
// Return Value:
|
||
//
|
||
// A value of true is returned in the brancd was taken. Otherwise,
|
||
// FALSE is returned.
|
||
//
|
||
//--
|
||
|
||
LEAF_ENTRY(Beq)
|
||
|
||
.set noreorder
|
||
li v0,1 // set branched true
|
||
beq a0,a1,10f // if eq, branch
|
||
lw v1,0(a2) // load unaligned data
|
||
move v0,zero // set branched false
|
||
10: j ra // return
|
||
sw v1,0(a3) // store unaligned value
|
||
.set reorder
|
||
|
||
.end Beq
|
||
|
||
LEAF_ENTRY(Bne)
|
||
|
||
.set noreorder
|
||
li v0,1 // set branched true
|
||
bne a0,a1,10f // if eq, branch
|
||
lw v1,0(a2) // load unaligned data
|
||
move v0,zero // set branched false
|
||
10: j ra // return
|
||
sw v1,0(a3) // store unaligned value
|
||
.set reorder
|
||
|
||
.end Bne
|
||
|
||
LEAF_ENTRY(Bc1f)
|
||
|
||
.set noreorder
|
||
mtc1 a0,f0 // set comparand 1
|
||
mtc1 a1,f2 // set comparand 2
|
||
li v0,1 // set branched true
|
||
c.eq.s f0,f2 // compare for equality
|
||
bc1f 10f // if f, branch
|
||
lw v1,0(a2) // load unaligned data
|
||
move v0,zero // set branched false
|
||
10: j ra // return
|
||
sw v1,0(a3) // store unaligned value
|
||
.set reorder
|
||
|
||
.end Bc1f
|
||
|
||
LEAF_ENTRY(Bc1t)
|
||
|
||
.set noreorder
|
||
mtc1 a0,f0 // set comparand 1
|
||
mtc1 a1,f2 // set comparand 2
|
||
li v0,1 // set branched true
|
||
c.eq.s f0,f2 // compare for equality
|
||
bc1t 10f // if t, branch
|
||
lw v1,0(a2) // load unaligned data
|
||
move v0,zero // set branched false
|
||
10: j ra // return
|
||
sw v1,0(a3) // store unaligned value
|
||
.set reorder
|
||
|
||
.end Bc1t
|
||
|
||
SBTTL("Unaligned BLEZ/BLTZ/BGEZ/BGTZ/BGEZAL/BLTZAL Branch Tests")
|
||
//++
|
||
//
|
||
// Routine Description:
|
||
//
|
||
// The following routines implement blez/bltz/bgez/bgtz/bgezal/bltzal
|
||
// tests with an unaligned load word instruction in the delay slot.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// a0 - Supplies the operand for branch test.
|
||
// a1 - Supplies a pointer to an unaligned word.
|
||
// a2 - Supplies a pointer to an aligned word that receives the result
|
||
// of the unaligned load.
|
||
//
|
||
// Return Value:
|
||
//
|
||
// A value of true is returned in the branch was taken. Otherwise,
|
||
// FALSE is returned.
|
||
//
|
||
//--
|
||
|
||
LEAF_ENTRY(Blez)
|
||
|
||
.set noreorder
|
||
li v0,1 // set branched true
|
||
blez a0,10f // if lez, branch
|
||
lw v1,0(a1) // load unaligned data
|
||
move v0,zero // set branched false
|
||
10: j ra // return
|
||
sw v1,0(a2) // store unaligned value
|
||
.set reorder
|
||
|
||
.end Blez
|
||
|
||
LEAF_ENTRY(Bltz)
|
||
|
||
.set noreorder
|
||
li v0,1 // set branched true
|
||
bltz a0,10f // if ltz, branch
|
||
lw v1,0(a1) // load unaligned data
|
||
move v0,zero // set branched false
|
||
10: j ra // return
|
||
sw v1,0(a2) // store unaligned value
|
||
.set reorder
|
||
|
||
.end Bltz
|
||
|
||
LEAF_ENTRY(Bgez)
|
||
|
||
.set noreorder
|
||
li v0,1 // set branched true
|
||
bgez a0,10f // if gez, branch
|
||
lw v1,0(a1) // load unaligned data
|
||
move v0,zero // set branched false
|
||
10: j ra // return
|
||
sw v1,0(a2) // store unaligned value
|
||
.set reorder
|
||
|
||
.end Bgez
|
||
|
||
LEAF_ENTRY(Bgtz)
|
||
|
||
.set noreorder
|
||
li v0,1 // set branched true
|
||
bgtz a0,10f // if gtz, branch
|
||
lw v1,0(a1) // load unaligned data
|
||
move v0,zero // set branched false
|
||
10: j ra // return
|
||
sw v1,0(a2) // store unaligned value
|
||
.set reorder
|
||
|
||
.end Bgtz
|
||
|
||
LEAF_ENTRY(Bgezal)
|
||
|
||
.set noreorder
|
||
sw ra,4 * 4(sp) // save return address
|
||
move v0,zero // set branched false
|
||
bgezal a0,10f // if gez, branch and link
|
||
lw v1,0(a1) // load unaligned data
|
||
lw ra,4 * 4(sp) // restore return address
|
||
sw v1,0(a2) // store unaligned value
|
||
j ra // return
|
||
nop //
|
||
|
||
10: j ra // return
|
||
li v0,1 // set branched true
|
||
.set reorder
|
||
|
||
.end Bgezal
|
||
|
||
LEAF_ENTRY(Bltzal)
|
||
|
||
.set noreorder
|
||
sw ra,4 * 4(sp) // save return address
|
||
move v0,zero // set branched false
|
||
bltzal a0,10f // if ltz, branch and link
|
||
lw v1,0(a1) // load unaligned data
|
||
lw ra,4 * 4(sp) // restore return address
|
||
sw v1,0(a2) // store unaligned value
|
||
j ra // return
|
||
nop //
|
||
|
||
10: j ra // return
|
||
li v0,1 // set branched true
|
||
.set reorder
|
||
|
||
.end Bltzal
|
||
|
||
SBTTL("Unaligned JAL/J Tests")
|
||
//++
|
||
//
|
||
// Routine Description:
|
||
//
|
||
// The following routines implement jal/j tests with an unaligned
|
||
// load word instruction in the delay slot.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// a0 - Supplies a pointer to an unaligned word.
|
||
// a1 - Supplies a pointer to an aligned word that receives the result
|
||
// of the unaligned load.
|
||
//
|
||
// Return Value:
|
||
//
|
||
// A value of true is returned in the brancd was taken. Otherwise,
|
||
// FALSE is returned.
|
||
//
|
||
//--
|
||
|
||
LEAF_ENTRY(Jal)
|
||
|
||
.set noreorder
|
||
sw ra,4 * 4(sp) // save return address
|
||
move v0,zero // set branched false
|
||
jal 10f // jump and link
|
||
lw v1,0(a0) // load unaligned data
|
||
lw ra,4 * 4(sp) // restore return address
|
||
sw v1,0(a1) // store unaligned value
|
||
j ra // return
|
||
nop //
|
||
|
||
10: j ra // return
|
||
li v0,1 // set branched true
|
||
.set reorder
|
||
|
||
.end Jal
|
||
|
||
LEAF_ENTRY(Jalr)
|
||
|
||
.set noreorder
|
||
sw ra,4 * 4(sp) // save return address
|
||
move v0,zero // set branched false
|
||
la t0,10f // get destination address
|
||
jal t0 // jump
|
||
lw v1,0(a0) // load unaligned data
|
||
lw ra,4 * 4(sp) // restore return address
|
||
sw v1,0(a1) // store unaligned value
|
||
j ra // return
|
||
nop //
|
||
|
||
10: j ra // jump back
|
||
li v0,1 // set branched true
|
||
.set reorder
|
||
|
||
.end Jalr
|
||
|
||
LEAF_ENTRY(J)
|
||
|
||
.set noreorder
|
||
sw ra,4 * 4(sp) // save return address
|
||
move v0,zero // set branched false
|
||
j 10f // jump
|
||
lw v1,0(a0) // load unaligned data
|
||
20: lw ra,4 * 4(sp) // restore return address
|
||
sw v1,0(a1) // store unaligned value
|
||
j ra // return
|
||
nop //
|
||
|
||
10: j 20b // jump back
|
||
li v0,1 // set branched true
|
||
.set reorder
|
||
|
||
.end J
|
||
|
||
LEAF_ENTRY(Jr)
|
||
|
||
.set noreorder
|
||
sw ra,4 * 4(sp) // save return address
|
||
move v0,zero // set branched false
|
||
la t0,10f // get destination address
|
||
j t0 // jump
|
||
lw v1,0(a0) // load unaligned data
|
||
20: lw ra,4 * 4(sp) // restore return address
|
||
sw v1,0(a1) // store unaligned value
|
||
j ra // return
|
||
nop //
|
||
|
||
10: j 20b // return
|
||
li v0,1 // set branched true
|
||
.set reorder
|
||
|
||
.end Jr
|