home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso / altsrc / articles / 11213 < prev    next >
Text File  |  1994-09-02  |  3KB  |  105 lines

  1. Path: wupost!news.utdallas.edu!corpgate!bnrgate!nott!torn!howland.reston.ans.net!europa.eng.gtefsd.com!news.umbc.edu!haven.umd.edu!zben-mac-ii.umd.edu!zben
  2. From: Charles B. Cranston <zben@ni.umd.edu>
  3. Newsgroups: comp.sys.powerpc,comp.arch.arithmetic,gnu.misc.discuss,comp.programming,sci.math,alt.sources
  4. Subject: Re: ANSWER: algorithm to perform 64-bit / 32-bit signed & unsigned divide
  5. Date: 2 Sep 1994 22:49:14 GMT
  6. Organization: Network Infrastructure U Maryland College Park
  7. Lines: 88
  8. Distribution: world
  9. Message-ID: <348a5a$dhs@haven.umd.edu>
  10. References: <joe.777905986@babel.ho.att.com>
  11. NNTP-Posting-Host: zben-mac-ii.umd.edu
  12. X-Newsreader: Nuntius Version 1.2
  13. X-XXMessage-ID: <AA8D242B3B020862@zben-mac-ii.umd.edu>
  14. X-XXDate: Fri, 2 Sep 1994 22:49:15 GMT
  15. Xref: wupost comp.sys.powerpc:28464 comp.arch.arithmetic:578 gnu.misc.discuss:18414 comp.programming:12159 sci.math:76261 alt.sources:11213
  16.  
  17. These are my first two assembly language programs on the power PC.
  18. dmult multiplies two 32 bit numbers to get a 64 bit result,
  19. ddiv divides a 32 bit number into a 64 bit number to get a 32 bit result.
  20. it probably needs to be protected from overflow...
  21.  
  22. =====
  23. dmult    ;
  24.     MulLW    R6,R3,R4        ; Generate low word of result
  25.     StW    R6,4(R5)        ; Save result
  26.     MulHWU    R7,R3,R4        ; Generate high word of result
  27.     StW    R7,0(R5)        ; Save result
  28.     BLR                ; Return to caller
  29. =====
  30. ddiv    ;
  31.     RLWINM    R6,R5,16,16,31        ; Get upper shifted B
  32.     RLWINM    R7,R5,16,0,15        ; Get lower shifted B
  33.     LI    R0,2            ; Do this loop twice
  34.     MTCtr    R0            ; Set count register
  35. @010    ;
  36.     RLWINM    R11,R10,16,0,15        ; Generate hi word second time through
  37.     AddI    R0,R6,1            ; Get [B upper 16] + 1 for trial division
  38.     DivWU    R10,R3,R0        ; Get estimate for high digit of quotient
  39.     RLWINM    R0,R10,16,0,15        ; Get shifted estimate
  40.     MulLW    R9,R0,R5        ; Get low word of [shifted digit times full B]
  41.     MulHWU    R8,R0,R5        ; Get high word of [shifted digit times full B]
  42.     SubFC    R4,R9,R4        ; Get remainder low
  43.     SubFE    R3,R8,R3        ; Get remainder high
  44. @040    ;
  45.     CmpLW    R3,R6            ; High order word says we need restoring subtract?
  46.     BGT    @050            ; Yes, go do restoring subtract
  47.     BNE    @060            ; No, we now have upper quotient digit
  48.     CmpLW    R4,R7            ; Low order word says we need restoring subtract?
  49.     BLT    @060            ; No, we now have upper quotient digit
  50. @050    ;
  51.     AddI    R10,R10,1        ; Increment quotient digit
  52.     SubFC    R4,R7,R4        ; Restoring subtract lower
  53.     SubFE    R3,R6,R3        ; Restoring subtract upper
  54.     B    @040            ; Back to test if another cycle needed
  55. #
  56. @060    ;
  57.     RLWINM    R3,R3,16,0,15        ; Left shift accumulator
  58.     RLWIMI    R3,R4,16,16,31        ; Left shift accumulator
  59.     RLWINM    R4,R4,16,0,15        ; Left shift accumulator
  60.     BDNZ    @010            ; Do this loop twice
  61. #
  62.     RLWIMI    R11,R10,0,16,31        ; Assemble estimated quotient
  63.     MR    R3,R11            ; Get answer
  64.     BLR                ; Return to caller
  65. =====
  66. void
  67. dotest(long x, long b)
  68. {
  69.     long q,a[2],dd[64];
  70.  
  71.     dmult(x,b,a);
  72.     q = ddiv(a[0],a[1],b);
  73.     if (q != x) {
  74.         dd[0] = x;
  75.         dd[1] = b;
  76.         dd[2] = a[0];
  77.         dd[3] = a[1];
  78.         dd[4] = q;
  79.         dumplong(5,dd);
  80.     }
  81.  
  82. }
  83.  
  84. void
  85. main()
  86. {
  87.     long i,x,b;
  88.  
  89.     InitGraf( (Ptr) &qd.thePort );
  90.     InitFonts();
  91.     InitWindows();
  92.     InitMenus();
  93.     TEInit();    
  94.     InitDialogs(nil);    
  95.     InitCursor();
  96.     display(message);
  97.  
  98.     for (i=0; i<1000000; i++) {
  99.         x = randlong();
  100.         b = randlong() | 0x80000000;
  101.         dotest(x,b);
  102.     }
  103.  
  104. }
  105.