File tree Expand file tree Collapse file tree 1 file changed +35
-0
lines changed
compiler-builtins/src/int Expand file tree Collapse file tree 1 file changed +35
-0
lines changed Original file line number Diff line number Diff line change @@ -43,6 +43,41 @@ intrinsics! {
4343
4444 ( ( rem as u64 ) << 32 ) | ( div as u64 )
4545 }
46+
47+ #[ naked]
48+ pub unsafe extern "C" fn __udivmodqi4( ) {
49+ // compute unsigned 8-bit `n / d` and `n % d`.
50+ //
51+ // Note: GCC implements a [non-standard calling convention](https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention) for this function.
52+ // Inputs:
53+ // R24: dividend
54+ // R22: divisor
55+ // Outputs:
56+ // R24: quotient (dividend / divisor)
57+ // R25: remainder (dividend % divisor)
58+ // Clobbers:
59+ // R23: loop counter
60+ core:: arch:: naked_asm!(
61+ // This assembly routine implements the [long division](https://en.wikipedia.org/wiki/Division_algorithm#Long_division) algorithm.
62+ // Bits shift out of the dividend and into the quotient, so R24 is used for both.
63+ "clr R25" , // remainder = 0
64+
65+ "ldi R23, 8" , // for each bit
66+ "1:" ,
67+ "lsl R24" , // shift the dividend MSb
68+ "rol R25" , // into the remainder LSb
69+
70+ "cp R25, R22" , // if remainder >= divisor
71+ "brlo 2f" ,
72+ "sub R25, R22" , // remainder -= divisor
73+ "sbr R24, 1" , // quotient |= 1
74+ "2:" ,
75+
76+ "dec R23" , // end loop
77+ "brne 1b" ,
78+ "ret" ,
79+ ) ;
80+ }
4681}
4782
4883intrinsics ! {
You can’t perform that action at this time.
0 commit comments