1*8d8a8ab5SRichard Henderson/* 2*8d8a8ab5SRichard Henderson * Minimal Alpha system boot code. 3*8d8a8ab5SRichard Henderson * 4*8d8a8ab5SRichard Henderson * Copyright Linaro Ltd 2019 5*8d8a8ab5SRichard Henderson */ 6*8d8a8ab5SRichard Henderson 7*8d8a8ab5SRichard Henderson .set noat 8*8d8a8ab5SRichard Henderson .set nomacro 9*8d8a8ab5SRichard Henderson .arch ev6 10*8d8a8ab5SRichard Henderson .text 11*8d8a8ab5SRichard Henderson 12*8d8a8ab5SRichard Henderson.macro load_pci_io reg 13*8d8a8ab5SRichard Henderson /* For typhoon, this is 14*8d8a8ab5SRichard Henderson * 0xfffffc0000000000 -- kseg identity map 15*8d8a8ab5SRichard Henderson * + 0x10000000000 -- typhoon pio base 16*8d8a8ab5SRichard Henderson * + 0x1fc000000 -- typhoon pchip0 pci base 17*8d8a8ab5SRichard Henderson * = 0xfffffd01fc000000 18*8d8a8ab5SRichard Henderson */ 19*8d8a8ab5SRichard Henderson ldah \reg, -3 /* ff..fd0000 */ 20*8d8a8ab5SRichard Henderson lda \reg, 0x1fc(\reg) /* ff..fd01fc */ 21*8d8a8ab5SRichard Henderson sll \reg, 24, \reg 22*8d8a8ab5SRichard Henderson.endm 23*8d8a8ab5SRichard Henderson 24*8d8a8ab5SRichard Henderson#define com1Rbr 0x3f8 25*8d8a8ab5SRichard Henderson#define com1Thr 0x3f8 26*8d8a8ab5SRichard Henderson#define com1Ier 0x3f9 27*8d8a8ab5SRichard Henderson#define com1Iir 0x3fa 28*8d8a8ab5SRichard Henderson#define com1Lcr 0x3fb 29*8d8a8ab5SRichard Henderson#define com1Mcr 0x3fc 30*8d8a8ab5SRichard Henderson#define com1Lsr 0x3fd 31*8d8a8ab5SRichard Henderson#define com1Msr 0x3fe 32*8d8a8ab5SRichard Henderson#define com1Scr 0x3ff 33*8d8a8ab5SRichard Henderson#define com1Dll 0x3f8 34*8d8a8ab5SRichard Henderson#define com1Dlm 0x3f9 35*8d8a8ab5SRichard Henderson 36*8d8a8ab5SRichard Henderson#define PAL_halt 0 37*8d8a8ab5SRichard Henderson#define PAL_wrent 52 38*8d8a8ab5SRichard Henderson#define PAL_wrkgp 55 39*8d8a8ab5SRichard Henderson 40*8d8a8ab5SRichard Henderson .text 41*8d8a8ab5SRichard Henderson .p2align 4 42*8d8a8ab5SRichard Henderson .globl _start 43*8d8a8ab5SRichard Henderson .ent _start 44*8d8a8ab5SRichard Henderson_start: 45*8d8a8ab5SRichard Henderson br $gp, .+4 46*8d8a8ab5SRichard Henderson ldah $gp, 0($gp) !gpdisp!1 47*8d8a8ab5SRichard Henderson lda $gp, 0($gp) !gpdisp!1 48*8d8a8ab5SRichard Henderson 49*8d8a8ab5SRichard Henderson ldah $sp, $stack_end($gp) !gprelhigh 50*8d8a8ab5SRichard Henderson lda $sp, $stack_end($sp) !gprellow 51*8d8a8ab5SRichard Henderson 52*8d8a8ab5SRichard Henderson /* Install kernel gp for exception handlers. */ 53*8d8a8ab5SRichard Henderson mov $gp, $16 54*8d8a8ab5SRichard Henderson call_pal PAL_wrkgp 55*8d8a8ab5SRichard Henderson 56*8d8a8ab5SRichard Henderson /* Install exception handlers. */ 57*8d8a8ab5SRichard Henderson ldah $16, entInt($gp) !gprelhigh 58*8d8a8ab5SRichard Henderson lda $16, entInt($16) !gprellow 59*8d8a8ab5SRichard Henderson lda $17, 0 60*8d8a8ab5SRichard Henderson call_pal PAL_wrent 61*8d8a8ab5SRichard Henderson 62*8d8a8ab5SRichard Henderson ldah $16, entArith($gp) !gprelhigh 63*8d8a8ab5SRichard Henderson lda $16, entArith($16) !gprellow 64*8d8a8ab5SRichard Henderson lda $17, 1 65*8d8a8ab5SRichard Henderson call_pal PAL_wrent 66*8d8a8ab5SRichard Henderson 67*8d8a8ab5SRichard Henderson ldah $16, entMM($gp) !gprelhigh 68*8d8a8ab5SRichard Henderson lda $16, entMM($16) !gprellow 69*8d8a8ab5SRichard Henderson lda $17, 2 70*8d8a8ab5SRichard Henderson call_pal PAL_wrent 71*8d8a8ab5SRichard Henderson 72*8d8a8ab5SRichard Henderson ldah $16, entIF($gp) !gprelhigh 73*8d8a8ab5SRichard Henderson lda $16, entIF($16) !gprellow 74*8d8a8ab5SRichard Henderson lda $17, 3 75*8d8a8ab5SRichard Henderson call_pal PAL_wrent 76*8d8a8ab5SRichard Henderson 77*8d8a8ab5SRichard Henderson ldah $16, entUna($gp) !gprelhigh 78*8d8a8ab5SRichard Henderson lda $16, entUna($16) !gprellow 79*8d8a8ab5SRichard Henderson lda $17, 4 80*8d8a8ab5SRichard Henderson call_pal PAL_wrent 81*8d8a8ab5SRichard Henderson 82*8d8a8ab5SRichard Henderson ldah $16, entSys($gp) !gprelhigh 83*8d8a8ab5SRichard Henderson lda $16, entSys($16) !gprellow 84*8d8a8ab5SRichard Henderson lda $17, 5 85*8d8a8ab5SRichard Henderson call_pal PAL_wrent 86*8d8a8ab5SRichard Henderson 87*8d8a8ab5SRichard Henderson /* 88*8d8a8ab5SRichard Henderson * Initialize COM1. 89*8d8a8ab5SRichard Henderson */ 90*8d8a8ab5SRichard Henderson load_pci_io $1 91*8d8a8ab5SRichard Henderson lda $2, 0x87 /* outb(0x87, com1Lcr); */ 92*8d8a8ab5SRichard Henderson stb $2, com1Lcr($1) 93*8d8a8ab5SRichard Henderson stb $31, com1Dlm($1) /* outb(0, com1Dlm); */ 94*8d8a8ab5SRichard Henderson lda $2, 3 /* baudconst 3 => 56000 */ 95*8d8a8ab5SRichard Henderson stb $2, com1Dll($1) /* outb(baudconst, com1Dll); */ 96*8d8a8ab5SRichard Henderson lda $2, 0x07 97*8d8a8ab5SRichard Henderson stb $2, com1Lcr($1) /* outb(0x07, com1Lcr) */ 98*8d8a8ab5SRichard Henderson lda $2, 0x0f 99*8d8a8ab5SRichard Henderson stb $2, com1Mcr($1) /* outb(0x0f, com1Mcr) */ 100*8d8a8ab5SRichard Henderson 101*8d8a8ab5SRichard Henderson bsr $26, main !samegp 102*8d8a8ab5SRichard Henderson 103*8d8a8ab5SRichard Henderson /* fall through to _exit */ 104*8d8a8ab5SRichard Henderson .end _start 105*8d8a8ab5SRichard Henderson 106*8d8a8ab5SRichard Henderson .globl _exit 107*8d8a8ab5SRichard Henderson .ent _exit 108*8d8a8ab5SRichard Henderson_exit: 109*8d8a8ab5SRichard Henderson .frame $sp, 0, $26, 0 110*8d8a8ab5SRichard Henderson .prologue 0 111*8d8a8ab5SRichard Henderson 112*8d8a8ab5SRichard Henderson /* We cannot return an error code. */ 113*8d8a8ab5SRichard Henderson call_pal PAL_halt 114*8d8a8ab5SRichard Henderson .end _exit 115*8d8a8ab5SRichard Henderson 116*8d8a8ab5SRichard Henderson/* 117*8d8a8ab5SRichard Henderson * We have received an exception that we don't handle. Log and exit. 118*8d8a8ab5SRichard Henderson */ 119*8d8a8ab5SRichard Henderson .ent log_exit 120*8d8a8ab5SRichard Hendersonlog_exit: 121*8d8a8ab5SRichard HendersonentInt: 122*8d8a8ab5SRichard HendersonentArith: 123*8d8a8ab5SRichard HendersonentMM: 124*8d8a8ab5SRichard HendersonentIF: 125*8d8a8ab5SRichard HendersonentUna: 126*8d8a8ab5SRichard HendersonentSys: 127*8d8a8ab5SRichard Henderson ldah $16, $errormsg($gp) !gprelhigh 128*8d8a8ab5SRichard Henderson lda $16, $errormsg($16) !gprellow 129*8d8a8ab5SRichard Henderson bsr $26, __sys_outs !samegp 130*8d8a8ab5SRichard Henderson bsr $26, _exit !samegp 131*8d8a8ab5SRichard Henderson .end log_exit 132*8d8a8ab5SRichard Henderson 133*8d8a8ab5SRichard Henderson .section .rodata 134*8d8a8ab5SRichard Henderson$errormsg: 135*8d8a8ab5SRichard Henderson .string "Terminated by exception.\n" 136*8d8a8ab5SRichard Henderson .previous 137*8d8a8ab5SRichard Henderson 138*8d8a8ab5SRichard Henderson /* 139*8d8a8ab5SRichard Henderson * Helper Functions 140*8d8a8ab5SRichard Henderson */ 141*8d8a8ab5SRichard Henderson 142*8d8a8ab5SRichard Henderson /* Output a single character to serial port */ 143*8d8a8ab5SRichard Henderson .global __sys_outc 144*8d8a8ab5SRichard Henderson .ent __sys_outc 145*8d8a8ab5SRichard Henderson__sys_outc: 146*8d8a8ab5SRichard Henderson .frame $sp, 0, $26, 0 147*8d8a8ab5SRichard Henderson .prologue 0 148*8d8a8ab5SRichard Henderson 149*8d8a8ab5SRichard Henderson load_pci_io $1 150*8d8a8ab5SRichard Henderson 151*8d8a8ab5SRichard Henderson /* 152*8d8a8ab5SRichard Henderson * while ((inb(com1Lsr) & 0x20) == 0) 153*8d8a8ab5SRichard Henderson * continue; 154*8d8a8ab5SRichard Henderson */ 155*8d8a8ab5SRichard Henderson1: ldbu $0, com1Lsr($1) 156*8d8a8ab5SRichard Henderson and $0, 0x20, $0 157*8d8a8ab5SRichard Henderson beq $0, 1b 158*8d8a8ab5SRichard Henderson 159*8d8a8ab5SRichard Henderson /* outb(c, com1Thr); */ 160*8d8a8ab5SRichard Henderson stb $16, com1Thr($1) 161*8d8a8ab5SRichard Henderson ret 162*8d8a8ab5SRichard Henderson .end __sys_outc 163*8d8a8ab5SRichard Henderson 164*8d8a8ab5SRichard Henderson /* Output a nul-terminated string to serial port */ 165*8d8a8ab5SRichard Henderson .global __sys_outs 166*8d8a8ab5SRichard Henderson .ent __sys_outs 167*8d8a8ab5SRichard Henderson__sys_outs: 168*8d8a8ab5SRichard Henderson .frame $sp, 0, $26, 0 169*8d8a8ab5SRichard Henderson .prologue 0 170*8d8a8ab5SRichard Henderson 171*8d8a8ab5SRichard Henderson load_pci_io $1 172*8d8a8ab5SRichard Henderson 173*8d8a8ab5SRichard Henderson ldbu $2, 0($16) 174*8d8a8ab5SRichard Henderson beq $2, 9f 175*8d8a8ab5SRichard Henderson 176*8d8a8ab5SRichard Henderson /* 177*8d8a8ab5SRichard Henderson * while ((inb(com1Lsr) & 0x20) == 0) 178*8d8a8ab5SRichard Henderson * continue; 179*8d8a8ab5SRichard Henderson */ 180*8d8a8ab5SRichard Henderson1: ldbu $0, com1Lsr($1) 181*8d8a8ab5SRichard Henderson and $0, 0x20, $0 182*8d8a8ab5SRichard Henderson beq $0, 1b 183*8d8a8ab5SRichard Henderson 184*8d8a8ab5SRichard Henderson /* outb(c, com1Thr); */ 185*8d8a8ab5SRichard Henderson stb $2, com1Thr($1) 186*8d8a8ab5SRichard Henderson 187*8d8a8ab5SRichard Henderson addq $16, 1, $16 188*8d8a8ab5SRichard Henderson ldbu $2, 0($16) 189*8d8a8ab5SRichard Henderson bne $2, 1b 190*8d8a8ab5SRichard Henderson 191*8d8a8ab5SRichard Henderson9: ret 192*8d8a8ab5SRichard Henderson .end __sys_outs 193*8d8a8ab5SRichard Henderson 194*8d8a8ab5SRichard Henderson/* 195*8d8a8ab5SRichard Henderson * Division routines that are normally in libc. 196*8d8a8ab5SRichard Henderson * 197*8d8a8ab5SRichard Henderson * These do not follow the C calling convention. Arguments are in $24+$25, 198*8d8a8ab5SRichard Henderson * the result is in $27. Register $28 may be clobbered; everything else 199*8d8a8ab5SRichard Henderson * must be saved. 200*8d8a8ab5SRichard Henderson * 201*8d8a8ab5SRichard Henderson * We store the remainder in $28, so that we can share code. 202*8d8a8ab5SRichard Henderson * 203*8d8a8ab5SRichard Henderson * We do not signal divide by zero. 204*8d8a8ab5SRichard Henderson */ 205*8d8a8ab5SRichard Henderson 206*8d8a8ab5SRichard Henderson/* 207*8d8a8ab5SRichard Henderson * Unsigned 64-bit division. 208*8d8a8ab5SRichard Henderson */ 209*8d8a8ab5SRichard Henderson 210*8d8a8ab5SRichard Henderson .globl __divqu 211*8d8a8ab5SRichard Henderson .ent __divqu 212*8d8a8ab5SRichard Henderson__divqu: 213*8d8a8ab5SRichard Henderson .frame $sp, 48, $23 214*8d8a8ab5SRichard Henderson subq $sp, 48, $sp 215*8d8a8ab5SRichard Henderson stq $0, 0($sp) 216*8d8a8ab5SRichard Henderson stq $1, 8($sp) 217*8d8a8ab5SRichard Henderson stq $2, 16($sp) 218*8d8a8ab5SRichard Henderson stq $3, 24($sp) 219*8d8a8ab5SRichard Henderson stq $4, 32($sp) 220*8d8a8ab5SRichard Henderson .prologue 0 221*8d8a8ab5SRichard Henderson 222*8d8a8ab5SRichard Henderson#define mask $0 223*8d8a8ab5SRichard Henderson#define divisor $1 224*8d8a8ab5SRichard Henderson#define compare $2 225*8d8a8ab5SRichard Henderson#define tmp1 $3 226*8d8a8ab5SRichard Henderson#define tmp2 $4 227*8d8a8ab5SRichard Henderson#define quotient $27 228*8d8a8ab5SRichard Henderson#define modulus $28 229*8d8a8ab5SRichard Henderson 230*8d8a8ab5SRichard Henderson mov $24, modulus 231*8d8a8ab5SRichard Henderson mov $25, divisor 232*8d8a8ab5SRichard Henderson mov $31, quotient 233*8d8a8ab5SRichard Henderson mov 1, mask 234*8d8a8ab5SRichard Henderson beq $25, 9f 235*8d8a8ab5SRichard Henderson 236*8d8a8ab5SRichard Henderson /* Shift left until divisor >= modulus. */ 237*8d8a8ab5SRichard Henderson1: cmpult divisor, modulus, compare 238*8d8a8ab5SRichard Henderson blt divisor, 2f 239*8d8a8ab5SRichard Henderson addq divisor, divisor, divisor 240*8d8a8ab5SRichard Henderson addq mask, mask, mask 241*8d8a8ab5SRichard Henderson bne compare, 1b 242*8d8a8ab5SRichard Henderson 243*8d8a8ab5SRichard Henderson2: addq quotient, mask, tmp2 244*8d8a8ab5SRichard Henderson srl mask, 1, mask 245*8d8a8ab5SRichard Henderson cmpule divisor, modulus, compare 246*8d8a8ab5SRichard Henderson subq modulus, divisor, tmp1 247*8d8a8ab5SRichard Henderson cmovne compare, tmp2, quotient 248*8d8a8ab5SRichard Henderson srl divisor, 1, divisor 249*8d8a8ab5SRichard Henderson cmovne compare, tmp1, modulus 250*8d8a8ab5SRichard Henderson bne mask, 2b 251*8d8a8ab5SRichard Henderson 252*8d8a8ab5SRichard Henderson9: ldq $0, 0($sp) 253*8d8a8ab5SRichard Henderson ldq $1, 8($sp) 254*8d8a8ab5SRichard Henderson ldq $2, 16($sp) 255*8d8a8ab5SRichard Henderson ldq $3, 24($sp) 256*8d8a8ab5SRichard Henderson ldq $4, 32($sp) 257*8d8a8ab5SRichard Henderson addq $sp, 48, $sp 258*8d8a8ab5SRichard Henderson ret $31, ($23), 1 259*8d8a8ab5SRichard Henderson 260*8d8a8ab5SRichard Henderson#undef mask 261*8d8a8ab5SRichard Henderson#undef divisor 262*8d8a8ab5SRichard Henderson#undef compare 263*8d8a8ab5SRichard Henderson#undef tmp1 264*8d8a8ab5SRichard Henderson#undef tmp2 265*8d8a8ab5SRichard Henderson#undef quotient 266*8d8a8ab5SRichard Henderson#undef modulus 267*8d8a8ab5SRichard Henderson 268*8d8a8ab5SRichard Henderson .end __divqu 269*8d8a8ab5SRichard Henderson 270*8d8a8ab5SRichard Henderson/* 271*8d8a8ab5SRichard Henderson * Unsigned 64-bit remainder. 272*8d8a8ab5SRichard Henderson * Note that __divqu above leaves the result in $28. 273*8d8a8ab5SRichard Henderson */ 274*8d8a8ab5SRichard Henderson 275*8d8a8ab5SRichard Henderson .globl __remqu 276*8d8a8ab5SRichard Henderson .ent __remqu 277*8d8a8ab5SRichard Henderson__remqu: 278*8d8a8ab5SRichard Henderson .frame $sp, 16, $23 279*8d8a8ab5SRichard Henderson subq $sp, 16, $sp 280*8d8a8ab5SRichard Henderson stq $23, 0($sp) 281*8d8a8ab5SRichard Henderson .prologue 0 282*8d8a8ab5SRichard Henderson 283*8d8a8ab5SRichard Henderson bsr $23, __divqu 284*8d8a8ab5SRichard Henderson 285*8d8a8ab5SRichard Henderson ldq $23, 0($sp) 286*8d8a8ab5SRichard Henderson mov $28, $27 287*8d8a8ab5SRichard Henderson addq $sp, 16, $sp 288*8d8a8ab5SRichard Henderson ret $31, ($23), 1 289*8d8a8ab5SRichard Henderson .end __remqu 290*8d8a8ab5SRichard Henderson 291*8d8a8ab5SRichard Henderson/* 292*8d8a8ab5SRichard Henderson * Signed 64-bit division. 293*8d8a8ab5SRichard Henderson */ 294*8d8a8ab5SRichard Henderson 295*8d8a8ab5SRichard Henderson .globl __divqs 296*8d8a8ab5SRichard Henderson .ent __divqs 297*8d8a8ab5SRichard Henderson__divqs: 298*8d8a8ab5SRichard Henderson .prologue 0 299*8d8a8ab5SRichard Henderson 300*8d8a8ab5SRichard Henderson /* Common case: both arguments are positive. */ 301*8d8a8ab5SRichard Henderson bis $24, $25, $28 302*8d8a8ab5SRichard Henderson bge $28, __divqu 303*8d8a8ab5SRichard Henderson 304*8d8a8ab5SRichard Henderson /* At least one argument is negative. */ 305*8d8a8ab5SRichard Henderson subq $sp, 32, $sp 306*8d8a8ab5SRichard Henderson stq $23, 0($sp) 307*8d8a8ab5SRichard Henderson stq $24, 8($sp) 308*8d8a8ab5SRichard Henderson stq $25, 16($sp) 309*8d8a8ab5SRichard Henderson 310*8d8a8ab5SRichard Henderson /* Compute absolute values. */ 311*8d8a8ab5SRichard Henderson subq $31, $24, $28 312*8d8a8ab5SRichard Henderson cmovlt $24, $28, $24 313*8d8a8ab5SRichard Henderson subq $31, $25, $28 314*8d8a8ab5SRichard Henderson cmovlt $25, $28, $25 315*8d8a8ab5SRichard Henderson 316*8d8a8ab5SRichard Henderson bsr $23, __divqu 317*8d8a8ab5SRichard Henderson 318*8d8a8ab5SRichard Henderson ldq $24, 8($sp) 319*8d8a8ab5SRichard Henderson ldq $25, 16($sp) 320*8d8a8ab5SRichard Henderson 321*8d8a8ab5SRichard Henderson /* -a / b = a / -b = -(a / b) */ 322*8d8a8ab5SRichard Henderson subq $31, $27, $23 323*8d8a8ab5SRichard Henderson xor $24, $25, $28 324*8d8a8ab5SRichard Henderson cmovlt $28, $23, $27 325*8d8a8ab5SRichard Henderson 326*8d8a8ab5SRichard Henderson ldq $23, 0($sp) 327*8d8a8ab5SRichard Henderson addq $sp, 32, $sp 328*8d8a8ab5SRichard Henderson ret $31, ($23), 1 329*8d8a8ab5SRichard Henderson .end __divqs 330*8d8a8ab5SRichard Henderson 331*8d8a8ab5SRichard Henderson/* 332*8d8a8ab5SRichard Henderson * Signed 64-bit remainder. 333*8d8a8ab5SRichard Henderson */ 334*8d8a8ab5SRichard Henderson 335*8d8a8ab5SRichard Henderson .globl __remqs 336*8d8a8ab5SRichard Henderson .ent __remqs 337*8d8a8ab5SRichard Henderson__remqs: 338*8d8a8ab5SRichard Henderson .prologue 0 339*8d8a8ab5SRichard Henderson 340*8d8a8ab5SRichard Henderson /* Common case: both arguments are positive. */ 341*8d8a8ab5SRichard Henderson bis $24, $25, $28 342*8d8a8ab5SRichard Henderson bge $28, __remqu 343*8d8a8ab5SRichard Henderson 344*8d8a8ab5SRichard Henderson /* At least one argument is negative. */ 345*8d8a8ab5SRichard Henderson subq $sp, 32, $sp 346*8d8a8ab5SRichard Henderson stq $23, 0($sp) 347*8d8a8ab5SRichard Henderson stq $24, 8($sp) 348*8d8a8ab5SRichard Henderson stq $25, 16($sp) 349*8d8a8ab5SRichard Henderson 350*8d8a8ab5SRichard Henderson /* Compute absolute values. */ 351*8d8a8ab5SRichard Henderson subq $31, $24, $28 352*8d8a8ab5SRichard Henderson cmovlt $24, $28, $24 353*8d8a8ab5SRichard Henderson subq $31, $25, $28 354*8d8a8ab5SRichard Henderson cmovlt $25, $28, $25 355*8d8a8ab5SRichard Henderson 356*8d8a8ab5SRichard Henderson bsr $23, __divqu 357*8d8a8ab5SRichard Henderson 358*8d8a8ab5SRichard Henderson ldq $23, 0($sp) 359*8d8a8ab5SRichard Henderson ldq $24, 8($sp) 360*8d8a8ab5SRichard Henderson ldq $25, 16($sp) 361*8d8a8ab5SRichard Henderson 362*8d8a8ab5SRichard Henderson /* -a % b = -(a % b); a % -b = a % b. */ 363*8d8a8ab5SRichard Henderson subq $31, $28, $27 364*8d8a8ab5SRichard Henderson cmovge $24, $28, $27 365*8d8a8ab5SRichard Henderson 366*8d8a8ab5SRichard Henderson addq $sp, 32, $sp 367*8d8a8ab5SRichard Henderson ret $31, ($23), 1 368*8d8a8ab5SRichard Henderson .end __remqs 369*8d8a8ab5SRichard Henderson 370*8d8a8ab5SRichard Henderson/* 371*8d8a8ab5SRichard Henderson * Unsigned 32-bit division. 372*8d8a8ab5SRichard Henderson */ 373*8d8a8ab5SRichard Henderson 374*8d8a8ab5SRichard Henderson .globl __divlu 375*8d8a8ab5SRichard Henderson .ent __divlu 376*8d8a8ab5SRichard Henderson__divlu: 377*8d8a8ab5SRichard Henderson .frame $sp, 32, $23 378*8d8a8ab5SRichard Henderson subq $sp, 32, $sp 379*8d8a8ab5SRichard Henderson stq $23, 0($sp) 380*8d8a8ab5SRichard Henderson stq $24, 8($sp) 381*8d8a8ab5SRichard Henderson stq $25, 16($sp) 382*8d8a8ab5SRichard Henderson .prologue 0 383*8d8a8ab5SRichard Henderson 384*8d8a8ab5SRichard Henderson /* Zero extend and use the 64-bit routine. */ 385*8d8a8ab5SRichard Henderson zap $24, 0xf0, $24 386*8d8a8ab5SRichard Henderson zap $25, 0xf0, $25 387*8d8a8ab5SRichard Henderson bsr $23, __divqu 388*8d8a8ab5SRichard Henderson 389*8d8a8ab5SRichard Henderson addl $27, 0, $27 390*8d8a8ab5SRichard Henderson ldq $23, 0($sp) 391*8d8a8ab5SRichard Henderson ldq $24, 8($sp) 392*8d8a8ab5SRichard Henderson ldq $25, 16($sp) 393*8d8a8ab5SRichard Henderson addq $sp, 32, $sp 394*8d8a8ab5SRichard Henderson ret $31, ($23), 1 395*8d8a8ab5SRichard Henderson .end __divlu 396*8d8a8ab5SRichard Henderson 397*8d8a8ab5SRichard Henderson/* 398*8d8a8ab5SRichard Henderson * Unsigned 32-bit remainder. 399*8d8a8ab5SRichard Henderson */ 400*8d8a8ab5SRichard Henderson 401*8d8a8ab5SRichard Henderson .globl __remlu 402*8d8a8ab5SRichard Henderson .ent __remlu 403*8d8a8ab5SRichard Henderson__remlu: 404*8d8a8ab5SRichard Henderson .frame $sp, 32, $23 405*8d8a8ab5SRichard Henderson subq $sp, 32, $sp 406*8d8a8ab5SRichard Henderson stq $23, 0($sp) 407*8d8a8ab5SRichard Henderson stq $24, 8($sp) 408*8d8a8ab5SRichard Henderson stq $25, 16($sp) 409*8d8a8ab5SRichard Henderson .prologue 0 410*8d8a8ab5SRichard Henderson 411*8d8a8ab5SRichard Henderson /* Zero extend and use the 64-bit routine. */ 412*8d8a8ab5SRichard Henderson zap $24, 0xf0, $24 413*8d8a8ab5SRichard Henderson zap $25, 0xf0, $25 414*8d8a8ab5SRichard Henderson bsr $23, __divqu 415*8d8a8ab5SRichard Henderson 416*8d8a8ab5SRichard Henderson /* Recall that the remainder is returned in $28. */ 417*8d8a8ab5SRichard Henderson addl $28, 0, $27 418*8d8a8ab5SRichard Henderson ldq $23, 0($sp) 419*8d8a8ab5SRichard Henderson ldq $24, 8($sp) 420*8d8a8ab5SRichard Henderson ldq $25, 16($sp) 421*8d8a8ab5SRichard Henderson addq $sp, 32, $sp 422*8d8a8ab5SRichard Henderson ret $31, ($23), 1 423*8d8a8ab5SRichard Henderson .end __remlu 424*8d8a8ab5SRichard Henderson 425*8d8a8ab5SRichard Henderson/* 426*8d8a8ab5SRichard Henderson * Signed 32-bit division. 427*8d8a8ab5SRichard Henderson */ 428*8d8a8ab5SRichard Henderson 429*8d8a8ab5SRichard Henderson .globl __divls 430*8d8a8ab5SRichard Henderson .ent __divls 431*8d8a8ab5SRichard Henderson__divls: 432*8d8a8ab5SRichard Henderson .frame $sp, 32, $23 433*8d8a8ab5SRichard Henderson subq $sp, 32, $sp 434*8d8a8ab5SRichard Henderson stq $23, 0($sp) 435*8d8a8ab5SRichard Henderson stq $24, 8($sp) 436*8d8a8ab5SRichard Henderson stq $25, 16($sp) 437*8d8a8ab5SRichard Henderson .prologue 0 438*8d8a8ab5SRichard Henderson 439*8d8a8ab5SRichard Henderson /* Sign extend. */ 440*8d8a8ab5SRichard Henderson addl $24, 0, $24 441*8d8a8ab5SRichard Henderson addl $25, 0, $25 442*8d8a8ab5SRichard Henderson 443*8d8a8ab5SRichard Henderson /* Compute absolute values. */ 444*8d8a8ab5SRichard Henderson subq $31, $24, $28 445*8d8a8ab5SRichard Henderson cmovlt $24, $28, $24 446*8d8a8ab5SRichard Henderson subq $31, $25, $28 447*8d8a8ab5SRichard Henderson cmovlt $25, $28, $25 448*8d8a8ab5SRichard Henderson 449*8d8a8ab5SRichard Henderson bsr $23, __divqu 450*8d8a8ab5SRichard Henderson 451*8d8a8ab5SRichard Henderson ldq $24, 8($sp) 452*8d8a8ab5SRichard Henderson ldq $25, 16($sp) 453*8d8a8ab5SRichard Henderson 454*8d8a8ab5SRichard Henderson /* Negate the unsigned result, if necessary. */ 455*8d8a8ab5SRichard Henderson xor $24, $25, $28 456*8d8a8ab5SRichard Henderson subl $31, $27, $23 457*8d8a8ab5SRichard Henderson addl $27, 0, $27 458*8d8a8ab5SRichard Henderson addl $28, 0, $28 459*8d8a8ab5SRichard Henderson cmovlt $28, $23, $27 460*8d8a8ab5SRichard Henderson 461*8d8a8ab5SRichard Henderson ldq $23, 0($sp) 462*8d8a8ab5SRichard Henderson addq $sp, 32, $sp 463*8d8a8ab5SRichard Henderson ret $31, ($23), 1 464*8d8a8ab5SRichard Henderson .end __divls 465*8d8a8ab5SRichard Henderson 466*8d8a8ab5SRichard Henderson/* 467*8d8a8ab5SRichard Henderson * Signed 32-bit remainder. 468*8d8a8ab5SRichard Henderson */ 469*8d8a8ab5SRichard Henderson 470*8d8a8ab5SRichard Henderson .globl __remls 471*8d8a8ab5SRichard Henderson .ent __remls 472*8d8a8ab5SRichard Henderson__remls: 473*8d8a8ab5SRichard Henderson .frame $sp, 32, $23 474*8d8a8ab5SRichard Henderson subq $sp, 32, $sp 475*8d8a8ab5SRichard Henderson stq $23, 0($sp) 476*8d8a8ab5SRichard Henderson stq $24, 8($sp) 477*8d8a8ab5SRichard Henderson stq $25, 16($sp) 478*8d8a8ab5SRichard Henderson .prologue 0 479*8d8a8ab5SRichard Henderson 480*8d8a8ab5SRichard Henderson /* Sign extend. */ 481*8d8a8ab5SRichard Henderson addl $24, 0, $24 482*8d8a8ab5SRichard Henderson addl $25, 0, $25 483*8d8a8ab5SRichard Henderson 484*8d8a8ab5SRichard Henderson /* Compute absolute values. */ 485*8d8a8ab5SRichard Henderson subq $31, $24, $28 486*8d8a8ab5SRichard Henderson cmovlt $24, $28, $24 487*8d8a8ab5SRichard Henderson subq $31, $25, $28 488*8d8a8ab5SRichard Henderson cmovlt $25, $28, $25 489*8d8a8ab5SRichard Henderson 490*8d8a8ab5SRichard Henderson bsr $23, __divqu 491*8d8a8ab5SRichard Henderson 492*8d8a8ab5SRichard Henderson ldq $23, 0($sp) 493*8d8a8ab5SRichard Henderson ldq $24, 8($sp) 494*8d8a8ab5SRichard Henderson ldq $25, 16($sp) 495*8d8a8ab5SRichard Henderson 496*8d8a8ab5SRichard Henderson /* Negate the unsigned result, if necessary. */ 497*8d8a8ab5SRichard Henderson subl $31, $28, $27 498*8d8a8ab5SRichard Henderson addl $28, 0, $28 499*8d8a8ab5SRichard Henderson cmovge $24, $28, $27 500*8d8a8ab5SRichard Henderson 501*8d8a8ab5SRichard Henderson addq $sp, 32, $sp 502*8d8a8ab5SRichard Henderson ret $31, ($23), 1 503*8d8a8ab5SRichard Henderson .end __remls 504*8d8a8ab5SRichard Henderson 505*8d8a8ab5SRichard Henderson .data 506*8d8a8ab5SRichard Henderson .p2align 4 507*8d8a8ab5SRichard Hendersonstack: 508*8d8a8ab5SRichard Henderson .skip 65536 509*8d8a8ab5SRichard Henderson$stack_end: 510*8d8a8ab5SRichard Henderson .type stack,@object 511*8d8a8ab5SRichard Henderson .size stack, . - stack 512