/* 32 and 64-bit millicode, original author Hewlett-Packard adapted for gcc by Paul Bame and Alan Modra . Copyright 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC and is released under the terms of of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. See the file COPYING in the top-level GCC source directory for a copy of the license. */ #include "milli.h" #ifdef L_remU /* ROUTINE: $$remU . Single precision divide for remainder with unsigned binary integers. . . The remainder must be dividend-(dividend/divisor)*divisor. . Divide by zero is trapped. INPUT REGISTERS: . arg0 == dividend . arg1 == divisor . mrp == return pc . sr0 == return space when called externally OUTPUT REGISTERS: . arg0 = undefined . arg1 = undefined . ret1 = remainder OTHER REGISTERS AFFECTED: . r1 = undefined SIDE EFFECTS: . Causes a trap under the following conditions: DIVIDE BY ZERO . Changes memory at the following places: NONE PERMISSIBLE CONTEXT: . Unwindable. . Does not create a stack frame. . Suitable for internal or external millicode. . Assumes the special millicode register conventions. DISCUSSION: . Calls other millicode routines using mrp: NONE . Calls other millicode routines: NONE */ RDEFINE(temp,r1) RDEFINE(rmndr,ret1) /* r29 */ SUBSPA_MILLI ATTR_MILLI .export $$remU,millicode .proc .callinfo millicode .entry GSYM($$remU) ldo -1(arg1),temp /* is there at most one bit set ? */ and,= arg1,temp,r0 /* if not, don't use power of 2 */ b LREF(regular_seq) addit,= 0,arg1,r0 /* trap on div by zero */ and arg0,temp,rmndr /* get the result for power of 2 */ MILLIRETN LSYM(regular_seq) comib,>=,n 0,arg1,LREF(special_case) subi 0,arg1,rmndr /* clear carry, negate the divisor */ ds r0,rmndr,r0 /* set V-bit to 1 */ add arg0,arg0,temp /* shift msb bit into carry */ ds r0,arg1,rmndr /* 1st divide step, if no carry */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 2nd divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 3rd divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 4th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 5th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 6th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 7th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 8th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 9th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 10th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 11th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 12th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 13th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 14th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 15th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 16th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 17th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 18th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 19th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 20th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 21st divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 22nd divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 23rd divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 24th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 25th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 26th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 27th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 28th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 29th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 30th divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 31st divide step */ addc temp,temp,temp /* shift temp with/into carry */ ds rmndr,arg1,rmndr /* 32nd divide step, */ comiclr,<= 0,rmndr,r0 add rmndr,arg1,rmndr /* correction */ MILLIRETN nop /* Putting >= on the last DS and deleting COMICLR does not work! */ LSYM(special_case) sub,>>= arg0,arg1,rmndr copy arg0,rmndr MILLIRETN nop .exit .procend .end #endif