diff --git a/clang/lib/Basic/Targets/AVR.cpp b/clang/lib/Basic/Targets/AVR.cpp --- a/clang/lib/Basic/Targets/AVR.cpp +++ b/clang/lib/Basic/Targets/AVR.cpp @@ -380,13 +380,13 @@ Builder.defineMacro("__AVR__"); Builder.defineMacro("__ELF__"); + if (ABI == "avrtiny") + Builder.defineMacro("__AVR_TINY__", "1"); + if (!this->CPU.empty()) { auto It = llvm::find_if( AVRMcus, [&](const MCUInfo &Info) { return Info.Name == this->CPU; }); - if (It->IsTiny) - Builder.defineMacro("__AVR_TINY__", "1"); - if (It != std::end(AVRMcus)) { Builder.defineMacro(It->DefineName); if (It->NumFlashBanks >= 1) diff --git a/clang/test/Preprocessor/avr-common.c b/clang/test/Preprocessor/avr-common.c --- a/clang/test/Preprocessor/avr-common.c +++ b/clang/test/Preprocessor/avr-common.c @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -E -dM -triple avr-unknown-unknown -target-cpu attiny13 /dev/null | FileCheck -match-full-lines --check-prefixes=CHECK,AVR %s +// RUN: %clang_cc1 -E -dM -triple avr-unknown-unknown -target-cpu avr25 /dev/null | FileCheck -match-full-lines --check-prefixes=CHECK,AVR %s // RUN: %clang_cc1 -E -dM -triple avr-unknown-unknown -target-cpu attiny4 /dev/null | FileCheck -match-full-lines --check-prefixes=CHECK,TINY %s +// RUN: %clang_cc1 -E -dM -triple avr-unknown-unknown -target-cpu avrtiny /dev/null | FileCheck -match-full-lines --check-prefixes=CHECK,TINY %s // CHECK: #define AVR 1 // CHECK: #define __AVR 1 diff --git a/compiler-rt/lib/builtins/avr/mulhi3.S b/compiler-rt/lib/builtins/avr/mulhi3.S --- a/compiler-rt/lib/builtins/avr/mulhi3.S +++ b/compiler-rt/lib/builtins/avr/mulhi3.S @@ -19,40 +19,53 @@ // return S; // } // +// __mulhi3 has special ABI, as the implementation of libgcc, R25:R24 is used +// to return result, while Rtmp/R21/R22/R23 are clobbered. +// //===----------------------------------------------------------------------===// .text .align 2 +#ifdef __AVR_TINY__ + .set __tmp_reg__, 16 + .set __zero_reg__, 17 +#else + .set __tmp_reg__, 0 + .set __zero_reg__, 1 +#endif + .globl __mulhi3 .type __mulhi3, @function __mulhi3: - eor r28, r28 - eor r20, r20 - eor r21, r21 ; Initialize the result to 0: `S = 0;`. + ; Use Rzero:Rtmp to store the result. + clr __tmp_reg__ + clr __zero_reg__ ; S = 0; __mulhi3_loop: - cp r24, r28 - cpc r25, r28 ; `while (A != 0) { ... }` - breq __mulhi3_end ; End the loop if A is 0. + clr r21 + cp r24, r21 + cpc r25, r21 + breq __mulhi3_end ; while (A != 0) { - mov r29, r24 - andi r29, 1 ; `if (A & 1) { ... }` - breq __mulhi3_loop_a ; Omit the accumulation (`S += B;`) if A's LSB is 0. - - add r20, r22 - adc r21, r23 ; Do the accumulation: `S += B;`. + mov r21, r24 + andi r21, 1 + breq __mulhi3_loop_a ; if (A & 1) + add __tmp_reg__, r22 + adc __zero_reg__, r23 ; S += B; __mulhi3_loop_a: - lsr r25 - ror r24 ; `A = ((unsigned int) A) >> 1;`. - lsl r22 - rol r23 ; `B <<= 1;` - - rjmp __mulhi3_loop + lsr r25 + ror r24 ; A = ((unsigned int) A) >> 1; + lsl r22 + rol r23 ; B <<= 1; + rjmp __mulhi3_loop ; } __mulhi3_end: - mov r24, r20 - mov r25, r21 - ret + ; Return the result via R25:R24. + mov r24, __tmp_reg__ + mov r25, __zero_reg__ + ; Restore __zero_reg__ to 0. + clr __zero_reg__ + ret ; return S; diff --git a/compiler-rt/lib/builtins/avr/mulqi3.S b/compiler-rt/lib/builtins/avr/mulqi3.S --- a/compiler-rt/lib/builtins/avr/mulqi3.S +++ b/compiler-rt/lib/builtins/avr/mulqi3.S @@ -8,24 +8,46 @@ // // The corresponding C code is something like: // -// int __mulqi3(char A, char B) { -// return __mulhi3((int) A, (int) B); +// char __mulqi3(char A, char B) { +// int S = 0; +// while (A != 0) { +// if (A & 1) +// S += B; +// B <<= 1; +// A = ((unsigned char) A) >> 1; +// } +// return S; // } // +// __mulqi3 has special ABI, as the implementation of libgcc, the result is +// returned via R24, while Rtmp and R22 are clobbered. +// //===----------------------------------------------------------------------===// .text .align 2 +#ifdef __AVR_TINY__ + .set __tmp_reg__, 16 +#else + .set __tmp_reg__, 0 +#endif + .globl __mulqi3 .type __mulqi3, @function __mulqi3: - mov r25, r24 - lsl r25 - sbc r25, r25 ; Promote A from char to int: `(int) A`. - mov r23, r22 - lsl r23 - sbc r23, r23 ; Promote B from char to int: `(int) B`. - rcall __mulhi3 ; `__mulhi3((int) A, (int) B);`. - ret + clr __tmp_reg__ ; S = 0; + +__mulqi3_loop: + cpi r24, 0 + breq __mulqi3_end ; while (A != 0) { + sbrc r24, 0 ; if (A & 1) + add __tmp_reg__, r22 ; S += B; + add r22, r22 ; B <<= 1; + lsr r24 ; A = ((unsigned char) A) >> 1; + rjmp __mulqi3_loop ; } + +__mulqi3_end: + mov r24, __tmp_reg__ + ret ; return S;