-/*
- * update profiling information for the user
- * addupc(pc, pr, ticks)
- * unsigned pc;
- * struct uprof *pr;
- * int ticks;
- */
-LEAF(addupc)
- lw v1, 8(a1) # get pr->pr_off
- subu a0, a0, v1 # pc -= pr->pr_off
- blt a0, zero, 1f # ignore if less than zero
- lw v0, 12(a1) # get pr->pr_scale
- multu v0, a0 # compute index into count table
- mflo v0
- srl v0, v0, 16 # shift v1,v0 >> 16
- mfhi v1
- sll v1, v1, 16
- or v0, v0, v1
- addu v0, v0, 1 # round up and
- and v0, v0, ~1 # align to short boundary
- lw v1, 4(a1) # get pr->pr_size
- bgeu v0, v1, 1f # ignore if index >= size
- lw v1, 0(a1) # get pr->pr_base
- addu v0, v0, v1 # add index and base
- li v1, ADDUPCERR # turn off profiling if fault
- bltz v0, addupcerr # can this happen?
- sw v1, UADDR+U_PCB_ONFAULT
- lh v1, 0(v0) # get old count
- addu v1, v1, a2 # add ticks
- sh v1, 0(v0) # save new count
- sw zero, UADDR+U_PCB_ONFAULT
-1:
- j ra
-addupcerr:
- sw zero, 12(a1) # pr->pr_scale = 0
- j ra
-END(addupc)
-