! as -Av8plus -o mulscc.o mulscc.s ; ld -o mulscc mulscc.o .equ SYSCALL_EXIT,1 .equ SYSCALL_WRITE,4 .equ STDOUT,1 ! This problem was noticed in the ____strtod_l_internal ! routine, Deep inside a Fortran program that is reading in ! Some floating point values from disk .globl _start _start: ! ! TEST1 - high bits in y ! set test1,%o1 call write_stdout nop tun_test1: ! Set some high bits in y ! have to use sllx to get them there set 0xff0fb28a, %o5 sllx %o5,8,%o5 or %o5,0x67,%o5 set 0x00989680, %o3 wr %g0, %o5, %y andcc %g0, %g0, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %o3, %g1 mulscc %g1, %g0, %g1 rd %y, %g3 ! g1 should be 00095b3c ! g3 should be a3858d80 set 0x00095b3c,%g2 cmp %g1,%g2 beq test1_pass nop test1_fail: set fail,%o1 ba test1_print nop test1_pass: set pass,%o1 test1_print: call write_stdout nop ! ! Test2 - high bits in src ! - to force issue, N^V should be 0 ! set test2,%o1 call write_stdout nop run_test2: set 0xffffffff,%g1 wr %g0, %g1, %y ! stores g0 XOR g1 into y (so, g1) sllx %g1,8,%g1 ! set some >32 bits in g1 set 0x00002c2f,%l0 andcc %g0, 0, %g2 ! sets v,c to 0. n=hi bit, z if zero ! since g0,0 we clear all flags mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 ! Proper result, g1 = 0x585e ! y = 0xffffa6a2 set 0x0000585e,%g2 cmp %g1,%g2 beq test2_pass nop test2_fail: set fail,%o1 ba test2_print nop test2_pass: set pass,%o1 test2_print: call write_stdout nop ! ! Test3 - high bits in src2 ! set test3,%o1 call write_stdout nop run_test3: set 0xffffffff,%l0 wr %g0, %l0, %y ! stores g0 XOR l0 into y (so, l0) sllx %l0,32,%l0 ! set some >32 bits in l0 or %l0,0xff,%l0 set 0x00002c2f,%g1 andcc %g0, 0, %g2 ! sets v,c to 0. n=hi bit, z if zero ! since g0,0 we clear all flags mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 mulscc %g1, %l0, %g1 larp: ! Proper result, g1 = 0x1fe ! y = 0x0000 2a31 set 0x1fe,%g2 cmp %g1,%g2 bne test3_fail nop rd %y, %g3 set 0x2a31,%g2 cmp %g2,%g3 beq test3_pass nop test3_fail: set fail,%o1 ba test3_print nop test3_pass: set pass,%o1 test3_print: call write_stdout nop !================================ ! Exit !================================ exit: mov 0,%o0 ! exit value mov SYSCALL_EXIT,%g1 ! put the exit syscall number in g1 ta 0x10 ! and exit !================================ ! WRITE_STDOUT !================================ ! %o1 has string write_stdout: set SYSCALL_WRITE,%g1 ! Write syscall in %g1 set STDOUT,%o0 ! 1 in %o0 (stdout) set 0,%o2 ! 0 (count) in %o2 str_loop1: ldub [%o1+%o2],%l0 ! load byte cmp %l0,%g0 ! compare against zero bnz str_loop1 ! if not nul, repeat ! BRANCH DELAY SLOT inc %o2 ! increment count dec %o2 ! correct count ta 0x10 ! run the syscall retl ! return nop .data fail: .ascii "Fail!\n\0" pass: .ascii "Pass\n\0" test1: .ascii "Test1: High bits in y : \0" test2: .ascii "Test2: High bits in src : \0" test3: .ascii "Test3: High bits in src2 : \0"