1 diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
2 --- gcc/config/avr/avr.c 2013-01-21 18:26:07.000000000 +0530
3 +++ gcc/config/avr/avr.c 2013-01-21 18:40:04.000000000 +0530
5 ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM) \
6 / SYMBOL_FLAG_MACH_DEP)
8 +#define TINY_ADIW(REG1, REG2, I) \
9 + "subi " #REG1 ",lo8(-(" #I "))" CR_TAB \
10 + "sbci " #REG2 ",hi8(-(" #I "))"
12 +#define TINY_SBIW(REG1, REG2, I) \
13 + "subi " #REG1 ",lo8((" #I "))" CR_TAB \
14 + "sbci " #REG2 ",hi8((" #I "))"
16 +#define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO)
17 +#define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO)
19 /* Known address spaces. The order must be the same as in the respective
20 enum from avr.h (or designated initialized must be used). */
21 const avr_addrspace_t avr_addrspace[] =
22 @@ -157,6 +168,9 @@ static bool avr_rtx_costs (rtx, int, int
23 /* Allocate registers from r25 to r8 for parameters for function calls. */
24 #define FIRST_CUM_REG 26
26 +/* Last call saved register */
27 +#define LAST_CALLEE_SAVED_REG (AVR_TINY ? 21 : 17)
29 /* Implicit target register of LPM instruction (R0) */
30 extern GTY(()) rtx lpm_reg_rtx;
32 @@ -306,7 +320,7 @@ avr_option_override (void)
33 avr_addr.rampy = 0x3A + avr_current_arch->sfr_offset;
34 avr_addr.rampx = 0x39 + avr_current_arch->sfr_offset;
35 avr_addr.rampd = 0x38 + avr_current_arch->sfr_offset;
36 - avr_addr.ccp = 0x34 + avr_current_arch->sfr_offset;
37 + avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_current_arch->sfr_offset;
39 /* SP: Stack Pointer (SP_H:SP_L) */
40 avr_addr.sp_l = 0x3D + avr_current_arch->sfr_offset;
41 @@ -338,8 +352,8 @@ avr_init_expanders (void)
42 all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
44 lpm_reg_rtx = all_regs_rtx[LPM_REGNO];
45 - tmp_reg_rtx = all_regs_rtx[TMP_REGNO];
46 - zero_reg_rtx = all_regs_rtx[ZERO_REGNO];
47 + tmp_reg_rtx = all_regs_rtx[AVR_TMP_REGNO];
48 + zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO];
50 lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
52 @@ -351,6 +365,11 @@ avr_init_expanders (void)
54 xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
55 xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
57 + /* TINY core does not have regs r10-r16, but avr-dimode.md expects them
60 + avr_have_dimode = false;
64 @@ -792,7 +811,7 @@ sequent_regs_live (void)
68 - for (reg = 0; reg < 18; ++reg)
69 + for (reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
73 @@ -903,7 +922,7 @@ emit_push_sfr (rtx sfr, bool frame_relat
74 RTX_FRAME_RELATED_P (insn) = 1;
76 /* PUSH __tmp_reg__ */
77 - emit_push_byte (TMP_REGNO, frame_related_p);
78 + emit_push_byte (AVR_TMP_REGNO, frame_related_p);
82 @@ -929,7 +948,8 @@ avr_prologue_setup_frame (HOST_WIDE_INT
85 && !cfun->machine->is_OS_task
86 - && !cfun->machine->is_OS_main);
87 + && !cfun->machine->is_OS_main
91 && (frame_pointer_needed
92 @@ -966,11 +986,11 @@ avr_prologue_setup_frame (HOST_WIDE_INT
93 /* Note that live_seq always contains r28+r29, but the other
94 registers to be saved are all below 18. */
96 - first_reg = 18 - (live_seq - 2);
97 + first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
99 for (reg = 29, offset = -live_seq + 1;
101 - reg = (reg == 28 ? 17 : reg - 1), ++offset)
102 + reg = (reg == 28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset)
106 @@ -1201,10 +1221,10 @@ expand_prologue (void)
107 emit_insn (gen_enable_interrupt ());
110 - emit_push_byte (ZERO_REGNO, true);
111 + emit_push_byte (AVR_ZERO_REGNO, true);
114 - emit_push_byte (TMP_REGNO, true);
115 + emit_push_byte (AVR_TMP_REGNO, true);
118 /* ??? There's no dwarf2 column reserved for SREG. */
119 @@ -1344,7 +1364,8 @@ expand_epilogue (bool sibcall_p)
122 && !cfun->machine->is_OS_task
123 - && !cfun->machine->is_OS_main);
124 + && !cfun->machine->is_OS_main
129 @@ -1502,14 +1523,14 @@ expand_epilogue (bool sibcall_p)
131 /* Restore SREG using tmp_reg as scratch. */
133 - emit_pop_byte (TMP_REGNO);
134 + emit_pop_byte (AVR_TMP_REGNO);
135 emit_move_insn (sreg_rtx, tmp_reg_rtx);
137 /* Restore tmp REG. */
138 - emit_pop_byte (TMP_REGNO);
139 + emit_pop_byte (AVR_TMP_REGNO);
141 /* Restore zero REG. */
142 - emit_pop_byte (ZERO_REGNO);
143 + emit_pop_byte (AVR_ZERO_REGNO);
147 @@ -2009,7 +2030,7 @@ avr_print_operand (FILE *file, rtx x, in
148 fprintf (file, "__RAMPX__");
149 else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
150 fprintf (file, "__RAMPD__");
151 - else if (AVR_XMEGA && ival == avr_addr.ccp)
152 + else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp)
153 fprintf (file, "__CCP__");
154 else if (ival == avr_addr.sreg) fprintf (file, "__SREG__");
155 else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__");
156 @@ -2052,6 +2073,13 @@ avr_print_operand (FILE *file, rtx x, in
158 avr_print_operand (file, XEXP (addr, 1), 0);
160 + else if (code == 'b')
162 + if (GET_CODE (addr) != PLUS)
163 + fatal_insn ("bad address, not (reg+disp):", addr);
165 + avr_print_operand_address (file, XEXP (addr, 0));
167 else if (code == 'p' || code == 'r')
169 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
170 @@ -2392,7 +2420,7 @@ avr_simplify_comparison_p (enum machine_
172 function_arg_regno_p(int r)
174 - return (r >= 8 && r <= 25);
175 + return (AVR_TINY ? r >= 20 && r <= 25 : r >= 8 && r <= 25);
178 /* Initializing the variable cum for the state at the beginning
179 @@ -2402,7 +2430,7 @@ void
180 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
181 tree fndecl ATTRIBUTE_UNUSED)
184 + cum->nregs = AVR_TINY ? 6 : 18;
185 cum->regno = FIRST_CUM_REG;
186 if (!libname && stdarg_p (fntype))
188 @@ -2900,6 +2928,25 @@ output_movhi (rtx insn, rtx xop[], int *
192 +/* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */
194 +avr_out_movqi_r_mr_reg_disp_tiny (rtx insn, rtx op[], int *plen)
198 + rtx x = XEXP (src, 0);
199 + op[2] = XEXP(x, 0);
201 + avr_asm_len (TINY_ADIW (%A2, %B2, %o1) CR_TAB
202 + "ld %0,%b1" , op, plen, -3);
204 + if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
205 + && !reg_unused_after (insn, XEXP (x,0)))
206 + avr_asm_len (TINY_SBIW (%A2, %B2, %o1), op, plen, 2);
212 out_movqi_r_mr (rtx insn, rtx op[], int *plen)
214 @@ -2913,13 +2960,18 @@ out_movqi_r_mr (rtx insn, rtx op[], int
215 ? avr_asm_len ("in %0,%i1", op, plen, -1)
216 : avr_asm_len ("lds %0,%m1", op, plen, -2);
218 - else if (GET_CODE (x) == PLUS
221 + if (GET_CODE (x) == PLUS
222 && REG_P (XEXP (x, 0))
223 && CONST_INT_P (XEXP (x, 1)))
225 /* memory access by reg+disp */
227 int disp = INTVAL (XEXP (x, 1));
230 + return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen);
232 if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
234 @@ -2941,25 +2993,105 @@ out_movqi_r_mr (rtx insn, rtx op[], int
236 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
237 it but I have this situation with extremal optimizing options. */
239 - avr_asm_len ("adiw r26,%o1" CR_TAB
240 - "ld %0,X", op, plen, -2);
242 + avr_asm_len ("adiw r26, %o1" CR_TAB
243 + "ld %0,X", op, plen, -2);
245 if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
246 && !reg_unused_after (insn, XEXP (x,0)))
248 - avr_asm_len ("sbiw r26,%o1", op, plen, 1);
249 + avr_asm_len ("sbiw r26, %o1", op, plen, 1);
255 - return avr_asm_len ("ldd %0,%1", op, plen, -1);
256 + return avr_asm_len ("ldd %0,%1", op, plen, -1);
259 return avr_asm_len ("ld %0,%1", op, plen, -1);
262 +/* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
264 +avr_out_movhi_r_mr_reg_no_disp_tiny (rtx op[], int *plen)
268 + rtx base = XEXP (src, 0);
270 + int reg_dest = true_regnum (dest);
271 + int reg_base = true_regnum (base);
275 + if (reg_dest == reg_base) /* R = (R) */
276 + return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
278 + "mov %A0,__tmp_reg__", op, plen, -3);
280 + return avr_asm_len ("ld %A0,%1" CR_TAB
281 + TINY_ADIW (%A2, %B2, 1) CR_TAB
283 + TINY_SBIW (%A2, %B2, 1), op, plen, -6);
287 +/* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
289 +avr_out_movhi_r_mr_reg_disp_tiny (rtx op[], int *plen)
293 + rtx base = XEXP (src, 0);
295 + int reg_dest = true_regnum (dest);
296 + int reg_base = true_regnum (XEXP (base, 0));
297 + op[2] = XEXP (base, 0);
299 + if (reg_base == reg_dest)
301 + return avr_asm_len (TINY_ADIW (%A2, %B2, %o1) CR_TAB
302 + "ld __tmp_reg__,%b1+" CR_TAB
303 + "ld %B0,%b1" CR_TAB
304 + "mov %A0,__tmp_reg__", op, plen, -5);
308 + return avr_asm_len (TINY_ADIW (%A2, %B2, %o1) CR_TAB
309 + "ld %A0,%b1+" CR_TAB
310 + "ld %B0,%b1" CR_TAB
311 + TINY_SBIW (%A2, %B2, %o1+1), op, plen, -6);
315 +/* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
317 +avr_out_movhi_r_mr_pre_dec_tiny (rtx insn, rtx op[], int *plen)
319 + int mem_volatile_p = 0;
322 + rtx base = XEXP (src, 0);
323 + op[2] = XEXP (base, 0);
325 + /* "volatile" forces reading low byte first, even if less efficient,
326 + for correct operation with 16-bit I/O registers. */
327 + mem_volatile_p = MEM_VOLATILE_P (src);
329 + if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
330 + fatal_insn ("incorrect insn:", insn);
332 + if (!mem_volatile_p)
333 + return avr_asm_len ("ld %B0,%1" CR_TAB
334 + "ld %A0,%1", op, plen, -2);
336 + return avr_asm_len (TINY_SBIW (%A2, %B2, 2) CR_TAB
337 + "ld %A0,%p1+" CR_TAB
338 + "ld %B0,%p1" CR_TAB
339 + TINY_SBIW (%A2, %B2, 1), op, plen, -6);
343 out_movhi_r_mr (rtx insn, rtx op[], int *plen)
345 @@ -2974,20 +3106,27 @@ out_movhi_r_mr (rtx insn, rtx op[], int
350 + return avr_out_movhi_r_mr_reg_no_disp_tiny (op, plen);
352 if (reg_dest == reg_base) /* R = (R) */
353 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
355 "mov %A0,__tmp_reg__", op, plen, -3);
357 if (reg_base != REG_X)
359 return avr_asm_len ("ld %A0,%1" CR_TAB
360 - "ldd %B0,%1+1", op, plen, -2);
362 + "ldd %B0,%1+1", op, plen, -2);
365 avr_asm_len ("ld %A0,X+" CR_TAB
366 "ld %B0,X", op, plen, -2);
368 if (!reg_unused_after (insn, base))
370 avr_asm_len ("sbiw r26,1", op, plen, 1);
375 @@ -2996,6 +3135,9 @@ out_movhi_r_mr (rtx insn, rtx op[], int
376 int disp = INTVAL (XEXP (base, 1));
377 int reg_base = true_regnum (XEXP (base, 0));
380 + return avr_out_movhi_r_mr_reg_disp_tiny (op, plen);
382 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
384 if (REGNO (XEXP (base, 0)) != REG_Y)
385 @@ -3007,7 +3149,7 @@ out_movhi_r_mr (rtx insn, rtx op[], int
386 "ldd %B0,Y+63" CR_TAB
387 "sbiw r28,%o1-62", op, plen, -4)
389 - : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
390 + : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
391 "sbci r29,hi8(-%o1)" CR_TAB
394 @@ -3041,6 +3183,9 @@ out_movhi_r_mr (rtx insn, rtx op[], int
396 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
399 + return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen);
401 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
402 fatal_insn ("incorrect insn:", insn);
404 @@ -3081,6 +3226,101 @@ out_movhi_r_mr (rtx insn, rtx op[], int
408 +avr_out_movsi_r_mr_reg_no_disp_tiny (rtx insn, rtx op[], int *l)
412 + rtx base = XEXP (src, 0);
413 + int reg_dest = true_regnum (dest);
414 + int reg_base = true_regnum (base);
417 + if (reg_dest == reg_base)
419 + /* "ld r26,-X" is undefined */
420 + return *l=9, (TINY_ADIW (%A2, %B2, 3) CR_TAB
422 + "ld %C0,-%1" CR_TAB
423 + "ld __tmp_reg__,-%1" CR_TAB
424 + TINY_SBIW (%A2, %B2, 1) CR_TAB
426 + "mov %B0,__tmp_reg__");
428 + else if (reg_dest == reg_base - 2)
430 + return *l=5, ("ld %A0,%1+" CR_TAB
431 + "ld %B0,%1+" CR_TAB
432 + "ld __tmp_reg__,%1+" CR_TAB
434 + "mov %C0,__tmp_reg__");
436 + else if (reg_unused_after (insn, base))
438 + return *l=4, ("ld %A0,%1+" CR_TAB
439 + "ld %B0,%1+" CR_TAB
440 + "ld %C0,%1+" CR_TAB
445 + return *l=6, ("ld %A0,%1+" CR_TAB
446 + "ld %B0,%1+" CR_TAB
447 + "ld %C0,%1+" CR_TAB
449 + TINY_SBIW (%A2, %B2, 3));
454 +avr_out_movsi_r_mr_reg_disp_tiny (rtx insn, rtx op[], int *l)
458 + rtx base = XEXP (src, 0);
459 + int reg_dest = true_regnum (dest);
460 + int reg_base = true_regnum (XEXP (base, 0));
461 + op[2] = XEXP (base, 0);
463 + if (reg_dest == reg_base)
465 + /* "ld r26,-X" is undefined */
466 + return *l=9, (TINY_ADIW (%A2, %B2, %o1+3) CR_TAB
467 + "ld %D0,%b1" CR_TAB
468 + "ld %C0,-%b1" CR_TAB
469 + "ld __tmp_reg__,-%b1" CR_TAB
470 + TINY_SBIW (%A2, %B2, 1) CR_TAB
471 + "ld %A0,%b1" CR_TAB
472 + "mov %B0,__tmp_reg__");
474 + else if (reg_dest == reg_base - 2)
476 + return *l=7, (TINY_ADIW (%A2, %B2, %o1) CR_TAB
477 + "ld %A0,%b1+" CR_TAB
478 + "ld %B0,%b1+" CR_TAB
479 + "ld __tmp_reg__,%b1+" CR_TAB
480 + "ld %D0,%b1" CR_TAB
481 + "mov %C0,__tmp_reg__");
483 + else if (reg_unused_after (insn, XEXP (base, 0)))
485 + return *l=6, (TINY_ADIW (%A2, %B2, %o1) CR_TAB
486 + "ld %A0,%b1+" CR_TAB
487 + "ld %B0,%b1+" CR_TAB
488 + "ld %C0,%b1+" CR_TAB
493 + return *l=8, (TINY_ADIW (%A2, %B2, %o1) CR_TAB
494 + "ld %A0,%b1+" CR_TAB
495 + "ld %B0,%b1+" CR_TAB
496 + "ld %C0,%b1+" CR_TAB
497 + "ld %D0,%b1" CR_TAB
498 + TINY_SBIW (%A2, %B2, %o1+3));
503 out_movsi_r_mr (rtx insn, rtx op[], int *l)
506 @@ -3095,6 +3335,9 @@ out_movsi_r_mr (rtx insn, rtx op[], int
511 + return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l);
513 if (reg_base == REG_X) /* (R26) */
515 if (reg_dest == REG_X)
516 @@ -3149,6 +3392,9 @@ out_movsi_r_mr (rtx insn, rtx op[], int
518 int disp = INTVAL (XEXP (base, 1));
521 + return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l);
523 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
525 if (REGNO (XEXP (base, 0)) != REG_Y)
526 @@ -3242,6 +3488,113 @@ out_movsi_r_mr (rtx insn, rtx op[], int
530 +avr_out_movsi_mr_r_reg_no_disp_tiny (rtx insn, rtx op[], int *l)
534 + rtx base = XEXP (dest, 0);
535 + int reg_base = true_regnum (base);
536 + int reg_src = true_regnum (src);
539 + if (reg_base == reg_src)
541 + /* "ld r26,-X" is undefined */
542 + if (reg_unused_after (insn, base))
544 + return *l=7, ("mov __tmp_reg__, %B1" CR_TAB
546 + TINY_ADIW (%A2, %B2, 1) CR_TAB
547 + "st %0+,__tmp_reg__" CR_TAB
548 + "st %0+,%C1" CR_TAB
553 + return *l=9, ("mov __tmp_reg__, %B1" CR_TAB
555 + TINY_ADIW (%A2, %B2, 1) CR_TAB
556 + "st %0+,__tmp_reg__" CR_TAB
557 + "st %0+,%C1" CR_TAB
558 + "st %0+,%D1" CR_TAB
559 + TINY_SBIW (%A2, %B2, 3));
562 + else if (reg_base == reg_src + 2)
564 + if (reg_unused_after (insn, base))
565 + return *l=7, ("mov __zero_reg__,%C1" CR_TAB
566 + "mov __tmp_reg__,%D1" CR_TAB
567 + "st %0+,%A1" CR_TAB
568 + "st %0+,%B1" CR_TAB
569 + "st %0+,__zero_reg__" CR_TAB
570 + "st %0,__tmp_reg__" CR_TAB
571 + "clr __zero_reg__");
573 + return *l=9, ("mov __zero_reg__,%C1" CR_TAB
574 + "mov __tmp_reg__,%D1" CR_TAB
575 + "st %0+,%A1" CR_TAB
576 + "st %0+,%B1" CR_TAB
577 + "st %0+,__zero_reg__" CR_TAB
578 + "st %0,__tmp_reg__" CR_TAB
579 + "clr __zero_reg__" CR_TAB
580 + TINY_SBIW (%A2, %B2, 3));
583 + return *l=6, ("st %0+,%A1" CR_TAB
584 + "st %0+,%B1" CR_TAB
585 + "st %0+,%C1" CR_TAB
587 + TINY_SBIW (%A2, %B2, 3));
591 +avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l)
595 + rtx base = XEXP (dest, 0);
596 + int reg_base = REGNO (XEXP (base, 0));
597 + int reg_src =true_regnum (src);
599 + op[2] = XEXP (base, 0);
601 + if (reg_base == reg_src)
604 + return ("mov __tmp_reg__,%A2" CR_TAB
605 + "mov __zero_reg__,%B2" CR_TAB
606 + TINY_ADIW (%A2, %B2, %o0) CR_TAB
607 + "st %b0+,__tmp_reg__" CR_TAB
608 + "st %b0+,__zero_reg__" CR_TAB
609 + "st %b0+,%C2" CR_TAB
610 + "st %b0,%D2" CR_TAB
611 + "clr __zero_reg__" CR_TAB
612 + TINY_SBIW (%A2, %B2, %o0+3));
614 + else if (reg_src == reg_base - 2)
617 + return ("mov __tmp_reg__,%C2" CR_TAB
618 + "mov __zero_reg__,%D2" CR_TAB
619 + TINY_ADIW (%A2, %B2, %o0) CR_TAB
620 + "st %b0+,%A0" CR_TAB
621 + "st %b0+,%B0" CR_TAB
622 + "st %b0+,__tmp_reg__" CR_TAB
623 + "st %b0,__zero_reg__" CR_TAB
624 + "clr __zero_reg__" CR_TAB
625 + TINY_SBIW (%A2, %B2, %o0+3));
628 + return (TINY_ADIW (%A2, %B2, %o0) CR_TAB
629 + "st %b0+,%A1" CR_TAB
630 + "st %b0+,%B1" CR_TAB
631 + "st %b0+,%C1" CR_TAB
632 + "st %b0,%D1" CR_TAB
633 + TINY_SBIW (%A2, %B2, %o0+3));
637 out_movsi_mr_r (rtx insn, rtx op[], int *l)
640 @@ -3261,6 +3614,9 @@ out_movsi_mr_r (rtx insn, rtx op[], int
642 if (reg_base > 0) /* (r) */
645 + return avr_out_movsi_mr_r_reg_no_disp_tiny (insn, op, l);
647 if (reg_base == REG_X) /* (R26) */
649 if (reg_src == REG_X)
650 @@ -3317,6 +3673,10 @@ out_movsi_mr_r (rtx insn, rtx op[], int
651 else if (GET_CODE (base) == PLUS) /* (R + i) */
653 int disp = INTVAL (XEXP (base, 1));
656 + return avr_out_movsi_mr_r_reg_disp_tiny (op, l);
658 reg_base = REGNO (XEXP (base, 0));
659 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
661 @@ -3476,6 +3836,75 @@ output_movsisf (rtx insn, rtx operands[]
662 /* Handle loads of 24-bit types from memory to register. */
665 +avr_out_load_psi_reg_no_disp_tiny (rtx insn, rtx *op, int *plen)
669 + rtx base = XEXP (src, 0);
670 + int reg_dest = true_regnum (dest);
671 + int reg_base = true_regnum (base);
674 + if (reg_base == reg_dest)
676 + return avr_asm_len (TINY_ADIW (%A2, %B2, 2) CR_TAB
678 + "ld __tmp_reg__,-%1" CR_TAB
679 + TINY_SBIW (%A2, %B2, 1) CR_TAB
681 + "mov %B0,__tmp_reg__", op, plen, -8);
685 + return avr_asm_len ("ld %A0,%1+" CR_TAB
686 + "ld %B0,%1+" CR_TAB
687 + "ld %C0,%1", op, plen, -3);
689 + if (reg_dest != reg_base - 2 &&
690 + !reg_unused_after (insn, base))
692 + avr_asm_len (TINY_SBIW (%A2, %B2, 2), op, plen, 2);
699 +avr_out_load_psi_reg_disp_tiny (rtx insn, rtx *op, int *plen)
703 + rtx base = XEXP (src, 0);
704 + int reg_dest = true_regnum (dest);
705 + int reg_base = true_regnum (base);
706 + op[2] = XEXP (base, 0);
708 + reg_base = true_regnum (XEXP (base, 0));
709 + if (reg_base == reg_dest)
711 + return avr_asm_len (TINY_ADIW (%A2, %B2, %o1+2) CR_TAB
712 + "ld %C0,%b1" CR_TAB
713 + "ld __tmp_reg__,-%b1" CR_TAB
714 + TINY_SBIW (%A2, %B2, 1) CR_TAB
715 + "ld %A0,%b1" CR_TAB
716 + "mov %B0,__tmp_reg__", op, plen, -8);
720 + avr_asm_len (TINY_ADIW (%A2, %B2, %o1) CR_TAB
721 + "ld %A0,%b1+" CR_TAB
722 + "ld %B0,%b1+" CR_TAB
723 + "ld %C0,%b1", op, plen, -5);
725 + if (reg_dest != (reg_base - 2)
726 + && !reg_unused_after (insn, XEXP (base, 0)))
727 + avr_asm_len (TINY_SBIW (%A2, %B2, %o1+2), op, plen, 2);
734 avr_out_load_psi (rtx insn, rtx *op, int *plen)
737 @@ -3486,6 +3915,9 @@ avr_out_load_psi (rtx insn, rtx *op, int
742 + return avr_out_load_psi_reg_no_disp_tiny (insn, op, plen);
744 if (reg_base == REG_X) /* (R26) */
746 if (reg_dest == REG_X)
747 @@ -3527,6 +3959,9 @@ avr_out_load_psi (rtx insn, rtx *op, int
748 else if (GET_CODE (base) == PLUS) /* (R + i) */
750 int disp = INTVAL (XEXP (base, 1));
753 + return avr_out_load_psi_reg_disp_tiny (insn, op, plen);
755 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
757 @@ -3604,6 +4039,85 @@ avr_out_load_psi (rtx insn, rtx *op, int
763 +avr_out_store_psi_reg_no_disp_tiny (rtx insn, rtx *op, int *plen)
767 + rtx base = XEXP (dest, 0);
768 + int reg_base = true_regnum (base);
769 + int reg_src = true_regnum (src);
772 + if (reg_base == reg_src)
774 + avr_asm_len ("st %0,%A1" CR_TAB
775 + "mov __tmp_reg__,%B1" CR_TAB
776 + TINY_ADIW (%A2, %B2, 1) CR_TAB /* st X+, r27 is undefined */
777 + "st %0+,__tmp_reg__" CR_TAB
778 + "st %0,%C1", op, plen, -6);
781 + else if (reg_src == reg_base - 2)
783 + avr_asm_len ("st %0,%A1" CR_TAB
784 + "mov __tmp_reg__,%C1" CR_TAB
785 + TINY_ADIW (%A2, %B2, 1) CR_TAB
786 + "st %0+,%B1" CR_TAB
787 + "st %0,__tmp_reg__", op, plen, 6);
791 + avr_asm_len ("st %0+,%A1" CR_TAB
792 + "st %0+,%B1" CR_TAB
793 + "st %0,%C1", op, plen, -3);
796 + if (!reg_unused_after (insn, base))
797 + avr_asm_len (TINY_SBIW (%A2, %B2, 2), op, plen, 2);
803 +avr_out_store_psi_reg_disp_tiny (rtx *op, int *plen)
807 + rtx base = XEXP (dest, 0);
808 + int reg_base = REGNO (XEXP (base, 0));
809 + int reg_src = true_regnum (src);
810 + op[2] = XEXP (base, 0);
812 + if (reg_src == reg_base)
814 + return avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
815 + "mov __zero_reg__,%B1" CR_TAB
816 + TINY_ADIW (%A2, %B2, %o0) CR_TAB
817 + "st %b0+,__tmp_reg__" CR_TAB
818 + "st %b0+,__zero_reg__" CR_TAB
819 + "st %b0,%C1" CR_TAB
820 + "clr __zero_reg__" CR_TAB
821 + TINY_SBIW (%A2, %B2, %o0+2), op, plen, -10);
823 + else if (reg_src == reg_base - 2)
825 + return avr_asm_len ("mov __tmp_reg__,%C1" CR_TAB
826 + TINY_ADIW (%A2, %B2, %o0) CR_TAB
827 + "st %b0+,%A1" CR_TAB
828 + "st %b0+,%B1" CR_TAB
829 + "st %b0,__tmp_reg__" CR_TAB
830 + TINY_SBIW (%A2, %B2, %o0+2), op, plen, -8);
833 + return avr_asm_len (TINY_ADIW (%A2, %B2, %o0) CR_TAB
834 + "st %b0+,%A1" CR_TAB
835 + "st %b0+,%B1" CR_TAB
836 + "st %b0,%C1" CR_TAB
837 + TINY_SBIW (%A2, %B2, %o0+2), op, plen, -7);
840 /* Handle store of 24-bit type from register or zero to memory. */
843 @@ -3621,6 +4135,9 @@ avr_out_store_psi (rtx insn, rtx *op, in
845 if (reg_base > 0) /* (r) */
848 + return avr_out_store_psi_reg_no_disp_tiny (insn, op, plen);
850 if (reg_base == REG_X) /* (R26) */
852 gcc_assert (!reg_overlap_mentioned_p (base, src));
853 @@ -3642,6 +4159,10 @@ avr_out_store_psi (rtx insn, rtx *op, in
854 else if (GET_CODE (base) == PLUS) /* (R + i) */
856 int disp = INTVAL (XEXP (base, 1));
859 + return avr_out_store_psi_reg_disp_tiny (op, plen);
861 reg_base = REGNO (XEXP (base, 0));
863 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
864 @@ -3758,6 +4279,31 @@ avr_out_movpsi (rtx insn, rtx *op, int *
869 +avr_out_movqi_mr_r_reg_disp_tiny (rtx insn, rtx op[], int *plen)
873 + rtx x = XEXP (dest, 0);
874 + op[2] = XEXP (x, 0);
876 + if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
878 + avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
879 + TINY_ADIW (%A2, %B2, %o0) CR_TAB
880 + "st %b0,__tmp_reg__", op, plen, -4);
884 + avr_asm_len (TINY_ADIW (%A2, %B2, %o0) CR_TAB
885 + "st %b0,%1" , op, plen, -3);
888 + if (!reg_unused_after (insn, XEXP (x,0)))
889 + avr_asm_len (TINY_SBIW (%A2, %B2, %o0), op, plen, 2);
895 out_movqi_mr_r (rtx insn, rtx op[], int *plen)
896 @@ -3780,6 +4326,9 @@ out_movqi_mr_r (rtx insn, rtx op[], int
898 int disp = INTVAL (XEXP (x, 1));
901 + return avr_out_movqi_mr_r_reg_disp_tiny (insn, op, plen);
903 if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
905 if (REGNO (XEXP (x, 0)) != REG_Y)
906 @@ -3934,6 +4483,76 @@ avr_out_movhi_mr_r_xmega (rtx insn, rtx
911 +avr_out_movhi_mr_r_reg_no_disp_tiny (rtx insn, rtx op[], int *plen)
915 + rtx base = XEXP (dest, 0);
916 + int reg_base = true_regnum (base);
917 + int reg_src = true_regnum (src);
918 + int mem_volatile_p = MEM_VOLATILE_P (dest);
921 + if (reg_base == reg_src)
923 + return !mem_volatile_p && reg_unused_after (insn, src)
924 + ? avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
926 + TINY_ADIW (%A2, %B2, 1) CR_TAB
927 + "st %0,__tmp_reg__", op, plen, -5)
928 + : avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
929 + TINY_ADIW (%A2, %B2, 1) CR_TAB
930 + "st %0,__tmp_reg__" CR_TAB
931 + TINY_SBIW (%A2, %B2, 1) CR_TAB
932 + "st %0, %A1", op, plen, -7);
935 + return !mem_volatile_p && reg_unused_after (insn, base)
936 + ? avr_asm_len ("st %0+,%A1" CR_TAB
937 + "st %0,%B1", op, plen, -2)
938 + : avr_asm_len (TINY_ADIW (%A2, %B2, 1) CR_TAB
940 + "st -%0,%A1", op, plen, -4);
944 +avr_out_movhi_mr_r_reg_disp_tiny (rtx op[], int *plen)
948 + rtx base = XEXP (dest, 0);
949 + int reg_base = REGNO (XEXP (base, 0));
950 + int reg_src = true_regnum (src);
951 + op[2] = XEXP (base, 0);
953 + return reg_src == reg_base
954 + ? avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
955 + "mov __zero_reg__,%B1" CR_TAB
956 + TINY_ADIW (%A2, %B2, %o0+1) CR_TAB
957 + "st %b0,__zero_reg__" CR_TAB
958 + "st -%b0,__tmp_reg__" CR_TAB
959 + "clr __zero_reg__" CR_TAB
960 + TINY_SBIW (%A2, %B2, %o0), op, plen, -9)
962 + : avr_asm_len (TINY_ADIW (%A2, %B2, %o0+1) CR_TAB
963 + "st %b0,%B1" CR_TAB
964 + "st -%b0,%A1" CR_TAB
965 + TINY_SBIW (%A2, %B2, %o0), op, plen, -6);
969 +avr_out_movhi_mr_r_post_inc_tiny (rtx op[], int *plen)
972 + rtx base = XEXP (dest, 0);
973 + op[2] = XEXP (base, 0);
975 + return avr_asm_len (TINY_ADIW (%A2, %B2, 1) CR_TAB
976 + "st %p0,%B1" CR_TAB
977 + "st -%p0,%A1" CR_TAB
978 + TINY_ADIW (%A2, %B2, 2), op, plen, -6);
982 out_movhi_mr_r (rtx insn, rtx op[], int *plen)
983 @@ -3964,6 +4583,9 @@ out_movhi_mr_r (rtx insn, rtx op[], int
988 + return avr_out_movhi_mr_r_reg_no_disp_tiny (insn, op, plen);
990 if (reg_base != REG_X)
991 return avr_asm_len ("std %0+1,%B1" CR_TAB
992 "st %0,%A1", op, plen, -2);
993 @@ -3992,6 +4614,10 @@ out_movhi_mr_r (rtx insn, rtx op[], int
994 else if (GET_CODE (base) == PLUS)
996 int disp = INTVAL (XEXP (base, 1));
999 + return avr_out_movhi_mr_r_reg_disp_tiny (op, plen);
1001 reg_base = REGNO (XEXP (base, 0));
1002 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
1004 @@ -4040,6 +4666,8 @@ out_movhi_mr_r (rtx insn, rtx op[], int
1005 if (!mem_volatile_p)
1006 return avr_asm_len ("st %0,%A1" CR_TAB
1007 "st %0,%B1", op, plen, -2);
1009 + return avr_out_movhi_mr_r_post_inc_tiny (op, plen);
1011 return REGNO (XEXP (base, 0)) == REG_X
1012 ? avr_asm_len ("adiw r26,1" CR_TAB
1013 @@ -4212,7 +4840,11 @@ avr_out_compare (rtx insn, rtx *xop, int
1015 || reg_unused_after (insn, xreg)))
1017 - avr_asm_len ("sbiw %0,%1", xop, plen, 1);
1019 + avr_asm_len (TINY_SBIW (%A0, %B0, %1), xop, plen, 2);
1021 + avr_asm_len ("sbiw %0,%1", xop, plen, 1);
1026 @@ -4222,7 +4854,9 @@ avr_out_compare (rtx insn, rtx *xop, int
1027 && compare_eq_p (insn)
1028 && reg_unused_after (insn, xreg))
1030 - return avr_asm_len ("adiw %0,%n1", xop, plen, 1);
1032 + ? avr_asm_len (TINY_ADIW (%A0, %B0, %n1), xop, plen, 2)
1033 + : avr_asm_len ("adiw %0,%n1", xop, plen, 1);
1037 @@ -7411,10 +8045,10 @@ avr_file_start (void)
1038 fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
1040 fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
1042 + if (AVR_XMEGA || AVR_TINY)
1043 fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
1044 - fprintf (asm_out_file, "__tmp_reg__ = %d\n", TMP_REGNO);
1045 - fprintf (asm_out_file, "__zero_reg__ = %d\n", ZERO_REGNO);
1046 + fprintf (asm_out_file, "__tmp_reg__ = %d\n", AVR_TMP_REGNO);
1047 + fprintf (asm_out_file, "__zero_reg__ = %d\n", AVR_ZERO_REGNO);
1051 @@ -7461,6 +8095,17 @@ order_regs_for_local_alloc (void)
1055 + static const int tiny_order_0[] = {
1064 + 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
1066 static const int order_1[] = {
1069 @@ -7473,6 +8118,17 @@ order_regs_for_local_alloc (void)
1073 + static const int tiny_order_1[] = {
1082 + 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
1084 static const int order_2[] = {
1087 @@ -7487,9 +8143,14 @@ order_regs_for_local_alloc (void)
1091 - const int *order = (TARGET_ORDER_1 ? order_1 :
1092 - TARGET_ORDER_2 ? order_2 :
1095 + Select specific register allocation order. Tiny Core (attiny4/5/9/10/20/40)
1096 + devices has only 16 registers, so different allocation order should be used
1098 + const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1) :
1099 + TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_1 : order_2) :
1100 + (AVR_TINY ? tiny_order_0 : order_0));
1102 for (i=0; i < ARRAY_SIZE (order_0); ++i)
1103 reg_alloc_order[i] = order[i];
1105 @@ -9151,7 +9812,7 @@ output_reload_in_const (rtx *op, rtx clo
1108 avr_asm_len (ldreg_p ? "ldi %0,0"
1109 - : ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
1110 + : AVR_ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
1111 : "mov %0,__zero_reg__",
1114 @@ -9350,6 +10011,50 @@ avr_output_addr_vec_elt (FILE *stream, i
1115 fprintf (stream, "\trjmp .L%d\n", value);
1119 +avr_conditional_register_usage(void) {
1124 + const int tiny_reg_alloc_order[] = {
1133 + 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
1136 + /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list
1137 + - R0-R15 are not available in Tiny Core devices
1138 + - R16 and R17 are fixed registers
1140 + for (i = 0; i <= 17; i++) {
1141 + fixed_regs[i] = 1;
1142 + call_used_regs[i] = 1;
1145 + /* Set R18 to R21 as callee saved registers
1146 + - R18, R19, R20 and R21 are the callee saved registers in Tiny Core devices
1148 + for (i = 18; i <= LAST_CALLEE_SAVED_REG; i++) {
1149 + call_used_regs[i] = 0;
1152 + /*update register allocation order for Tiny Core devices */
1153 + for (i=0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++) {
1154 + reg_alloc_order[i] = tiny_reg_alloc_order[i];
1157 + CLEAR_HARD_REG_SET(reg_class_contents[(int)ADDW_REGS]);
1158 + CLEAR_HARD_REG_SET(reg_class_contents[(int)NO_LD_REGS]);
1162 /* Returns true if SCRATCH are safe to be allocated as a scratch
1163 registers (for a define_peephole2) in the current function. */
1165 @@ -9495,13 +10200,20 @@ avr_asm_out_dtor (rtx symbol, int priori
1167 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1169 - if (TYPE_MODE (type) == BLKmode)
1171 - HOST_WIDE_INT size = int_size_in_bytes (type);
1172 - return (size == -1 || size > 8);
1174 + HOST_WIDE_INT size = int_size_in_bytes (type);
1175 + HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8;
1177 + /* In avr, there are 8 return registers. But, for Tiny Core
1178 + (attiny4/5/9/10/20/40) devices, only 4 registers available.
1179 + Return true if size is unknown or greater than the limit */
1180 + if ((size == -1) || (size > ret_size_limit))
1190 /* Worker function for CASE_VALUES_THRESHOLD. */
1191 @@ -10949,6 +11661,9 @@ avr_fold_builtin (tree fndecl, int n_arg
1192 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
1193 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
1195 +#undef TARGET_CONDITIONAL_REGISTER_USAGE
1196 +#define TARGET_CONDITIONAL_REGISTER_USAGE avr_conditional_register_usage
1198 #undef TARGET_HARD_REGNO_SCRATCH_OK
1199 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
1200 #undef TARGET_CASE_VALUES_THRESHOLD
1201 diff -Naurp gcc/config/avr/avr-c.c gcc/config/avr/avr-c.c
1202 --- gcc/config/avr/avr-c.c 2012-09-05 17:49:47.000000000 +0530
1203 +++ gcc/config/avr/avr-c.c 2013-01-21 18:40:04.000000000 +0530
1204 @@ -113,6 +113,23 @@ avr_cpu_cpp_builtins (struct cpp_reader
1207 cpp_define (pfile, "__AVR_XMEGA__");
1211 + cpp_define (pfile, "__AVR_TINY__");
1213 + /* Define macro "__AVR_TINY_PM_BASE_ADDRESS__" with mapped program memory
1214 + start address. This macro shall be referred where mapped program memory
1215 + is accessed. (Eg. copying data section (do_copy_data) contents to data
1218 + Program memory of AVR_TINY devices can not be accessed directly, it has
1219 + been mapped to the data memory. For AVR_TINY devices (ATtiny4/ 5/ 9/ 10/
1220 + 20 and 40) mapped program memory starts at 0x4000.
1222 + cpp_define (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x4000");
1225 if (avr_current_arch->have_eijmp_eicall)
1227 cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
1228 diff -Naurp gcc/config/avr/avr-devices.c gcc/config/avr/avr-devices.c
1229 --- gcc/config/avr/avr-devices.c 2012-08-06 20:04:27.000000000 +0530
1230 +++ gcc/config/avr/avr-devices.c 2013-01-21 18:40:04.000000000 +0530
1231 @@ -30,29 +30,30 @@ const struct base_arch_s
1234 /* unknown device specified */
1235 - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, NULL, "avr2" },
1236 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, NULL, "avr2" },
1238 - A M J LM E E E X R d S S O A
1239 - S U M PO L L I M A a t F ff r
1240 - M L P MV P P J E M t a R s c
1241 - XW M M M G P a r e h
1243 - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "1", "avr1" },
1244 - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "2", "avr2" },
1245 - { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, "25", "avr25" },
1246 - { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "3", "avr3" },
1247 - { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0x0060, 32, "31", "avr31" },
1248 - { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0x0060, 32, "35", "avr35" },
1249 - { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, "4", "avr4" },
1250 - { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0x0060, 32, "5", "avr5" },
1251 - { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 32, "51", "avr51" },
1252 - { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0x0060, 32, "6", "avr6" },
1253 + A M J LM E E E X R T d S S O A
1254 + S U M PO L L I M A I a t F ff r
1255 + M L P MV P P J E M N t a R s c
1256 + XW M M M G P Y a r e h
1258 + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "1", "avr1" },
1259 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "2", "avr2" },
1260 + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "25", "avr25" },
1261 + { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "3", "avr3" },
1262 + { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, "31", "avr31" },
1263 + { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "35", "avr35" },
1264 + { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "4", "avr4" },
1265 + { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "5", "avr5" },
1266 + { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0x0060, 32, "51", "avr51" },
1267 + { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 32, "6", "avr6" },
1269 - { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0x2000, 0, "102", "avrxmega2" },
1270 - { 0, 1, 1, 1, 1, 1, 0, 1, 0, 0x2000, 0, "104", "avrxmega4" },
1271 - { 0, 1, 1, 1, 1, 1, 0, 1, 1, 0x2000, 0, "105", "avrxmega5" },
1272 - { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, 0, "106", "avrxmega6" },
1273 - { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0x2000, 0, "107", "avrxmega7" }
1274 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x0040, 0, "100", "avrtiny" },
1275 + { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0x2000, 0, "102", "avrxmega2" },
1276 + { 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0x2000, 0, "104", "avrxmega4" },
1277 + { 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0x2000, 0, "105", "avrxmega5" },
1278 + { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0x2000, 0, "106", "avrxmega6" },
1279 + { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, 0, "107", "avrxmega7" }
1282 const struct mcu_type_s avr_mcu_types[] = {
1283 diff -Naurp gcc/config/avr/avr.h gcc/config/avr/avr.h
1284 --- gcc/config/avr/avr.h 2013-01-21 18:26:07.000000000 +0530
1285 +++ gcc/config/avr/avr.h 2013-01-21 18:40:04.000000000 +0530
1286 @@ -52,6 +52,9 @@ struct base_arch_s
1287 /* This core has the RAMPD special function register
1288 and thus also the RAMPX, RAMPY and RAMPZ registers. */
1291 + /* This is a TINY core. */
1294 /* Default start of data section address for architecture. */
1295 int default_data_section_start;
1296 @@ -83,6 +86,7 @@ enum avr_arch
1304 @@ -213,6 +217,7 @@ enum
1305 #define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL)
1307 #define AVR_XMEGA (avr_current_arch->xmega_p)
1308 +#define AVR_TINY (avr_current_arch->tiny_p)
1310 #define BITS_BIG_ENDIAN 0
1311 #define BYTES_BIG_ENDIAN 0
1312 @@ -342,7 +347,6 @@ enum reg_class {
1313 ALL_REGS, LIM_REG_CLASSES
1317 #define N_REG_CLASSES (int)LIM_REG_CLASSES
1319 #define REG_CLASS_NAMES { \
1320 @@ -417,7 +421,7 @@ enum reg_class {
1322 #define ARG_POINTER_REGNUM 34
1324 -#define STATIC_CHAIN_REGNUM 2
1325 +#define STATIC_CHAIN_REGNUM ((AVR_TINY) ? 18 :2)
1327 #define ELIMINABLE_REGS { \
1328 {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
1329 diff -Naurp gcc/config/avr/avr-mcus.def gcc/config/avr/avr-mcus.def
1330 --- gcc/config/avr/avr-mcus.def 2012-09-10 16:16:27.000000000 +0530
1331 +++ gcc/config/avr/avr-mcus.def 2013-01-21 18:40:04.000000000 +0530
1332 @@ -231,6 +231,14 @@ AVR_MCU ("atxmega256d3", ARCH_AVRXME
1333 AVR_MCU ("avrxmega7", ARCH_AVRXMEGA7, NULL, 0, 0, 0x2000, 3, "x128a1")
1334 AVR_MCU ("atxmega128a1", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1__", 0, 0, 0x2000, 3, "x128a1")
1335 AVR_MCU ("atxmega128a1u", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1U__", 0, 0, 0x2000, 3, "x128a1u")
1337 +AVR_MCU ("avrtiny", ARCH_AVRTINY, NULL, 0, 0, 0x0040, 1, "tn10")
1338 +AVR_MCU ("attiny4", ARCH_AVRTINY, "__AVR_ATtiny4__", 0, 0, 0x0040, 1, "tn4")
1339 +AVR_MCU ("attiny5", ARCH_AVRTINY, "__AVR_ATtiny5__", 0, 0, 0x0040, 1, "tn5")
1340 +AVR_MCU ("attiny9", ARCH_AVRTINY, "__AVR_ATtiny9__", 0, 0, 0x0040, 1, "tn9")
1341 +AVR_MCU ("attiny10", ARCH_AVRTINY, "__AVR_ATtiny10__", 0, 0, 0x0040, 1, "tn10")
1342 +AVR_MCU ("attiny20", ARCH_AVRTINY, "__AVR_ATtiny20__", 0, 0, 0x0040, 1, "tn20")
1343 +AVR_MCU ("attiny40", ARCH_AVRTINY, "__AVR_ATtiny40__", 0, 0, 0x0040, 1, "tn40")
1344 /* Assembler only. */
1345 AVR_MCU ("avr1", ARCH_AVR1, NULL, 0, 0, 0x0060, 1, "s1200")
1346 AVR_MCU ("at90s1200", ARCH_AVR1, "__AVR_AT90S1200__", 0, 0, 0x0060, 1, "s1200")
1347 diff -Naurp gcc/config/avr/avr.md gcc/config/avr/avr.md
1348 --- gcc/config/avr/avr.md 2012-03-22 20:36:57.000000000 +0530
1349 +++ gcc/config/avr/avr.md 2013-01-21 18:40:04.000000000 +0530
1351 (ZERO_REGNO 1) ; zero register r1
1355 + [ (TMP_REGNO_TINY 16) ; r16 is temp register for TINY10
1356 + (ZERO_REGNO_TINY 17) ; r17 is zero register for TINY10
1359 (define_c_enum "unspec"
1362 @@ -158,9 +163,10 @@
1363 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
1364 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
1365 ;; no_xmega: non-XMEGA core xmega : XMEGA core
1366 +;; no_tiny: non-TINY core tiny : TINY core
1369 - "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
1370 + "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega, no_tiny,tiny,
1372 (const_string "standard"))
1374 @@ -212,9 +218,18 @@
1375 (match_test "AVR_XMEGA"))
1378 + (and (eq_attr "isa" "tiny")
1379 + (match_test "AVR_TINY"))
1382 (and (eq_attr "isa" "no_xmega")
1383 (match_test "!AVR_XMEGA"))
1386 + (and (eq_attr "isa" "no_tiny")
1387 + (match_test "!AVR_TINY"))
1393 @@ -5413,18 +5428,18 @@
1394 (set_attr "cc" "clobber")])
1396 (define_insn "delay_cycles_2"
1397 - [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
1398 + [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
1400 UNSPECV_DELAY_CYCLES)
1401 (set (match_operand:BLK 1 "" "")
1402 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
1403 - (clobber (match_scratch:HI 2 "=&w"))]
1404 + (clobber (match_scratch:HI 2 "=&w,&d"))]
1410 - [(set_attr "length" "4")
1412 + ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\;1: sbiw %A2,1\;brne 1b
1413 + ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\;1: subi %A2,1\;sbci %B2,0\;brne 1b"
1414 + [(set_attr "length" "4,5")
1415 + (set_attr "isa" "no_tiny,tiny")
1416 (set_attr "cc" "clobber")])
1418 (define_insn "delay_cycles_3"
1419 diff -Naurp gcc/config/avr/avr-tables.opt gcc/config/avr/avr-tables.opt
1420 --- gcc/config/avr/avr-tables.opt 2012-09-20 12:53:55.000000000 +0530
1421 +++ gcc/config/avr/avr-tables.opt 2013-01-21 18:40:04.000000000 +0530
1422 @@ -579,20 +579,41 @@ EnumValue
1423 Enum(avr_mcu) String(atxmega128a1u) Value(184)
1426 -Enum(avr_mcu) String(avr1) Value(185)
1427 +Enum(avr_mcu) String(avrtiny) Value(185)
1430 -Enum(avr_mcu) String(at90s1200) Value(186)
1431 +Enum(avr_mcu) String(attiny4) Value(186)
1434 -Enum(avr_mcu) String(attiny11) Value(187)
1435 +Enum(avr_mcu) String(attiny5) Value(187)
1438 -Enum(avr_mcu) String(attiny12) Value(188)
1439 +Enum(avr_mcu) String(attiny9) Value(188)
1442 -Enum(avr_mcu) String(attiny15) Value(189)
1443 +Enum(avr_mcu) String(attiny10) Value(189)
1446 -Enum(avr_mcu) String(attiny28) Value(190)
1447 +Enum(avr_mcu) String(attiny20) Value(190)
1450 +Enum(avr_mcu) String(attiny40) Value(191)
1453 +Enum(avr_mcu) String(avr1) Value(192)
1456 +Enum(avr_mcu) String(at90s1200) Value(193)
1459 +Enum(avr_mcu) String(attiny11) Value(194)
1462 +Enum(avr_mcu) String(attiny12) Value(195)
1465 +Enum(avr_mcu) String(attiny15) Value(196)
1468 +Enum(avr_mcu) String(attiny28) Value(197)
1470 diff -Naurp gcc/config/avr/t-multilib gcc/config/avr/t-multilib
1471 --- gcc/config/avr/t-multilib 2012-09-20 12:53:55.000000000 +0530
1472 +++ gcc/config/avr/t-multilib 2013-01-21 18:40:04.000000000 +0530
1474 # along with GCC; see the file COPYING3. If not see
1475 # <http://www.gnu.org/licenses/>.
1477 -MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7 msp8
1478 +MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7/mmcu=avrtiny msp8
1480 -MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack avr25/tiny-stack
1481 +MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny tiny-stack avr25/tiny-stack
1483 MULTILIB_EXCEPTIONS = \
1485 @@ -37,7 +37,8 @@ MULTILIB_EXCEPTIONS = \
1486 mmcu=avrxmega4/msp8 \
1487 mmcu=avrxmega5/msp8 \
1488 mmcu=avrxmega6/msp8 \
1489 - mmcu=avrxmega7/msp8
1490 + mmcu=avrxmega7/msp8 \
1493 MULTILIB_MATCHES = \
1494 mmcu?avr2=mmcu?at90s2313 \
1495 @@ -210,4 +211,10 @@ MULTILIB_MATCHES = \
1496 mmcu?avrxmega6=mmcu?atxmega256a3bu \
1497 mmcu?avrxmega6=mmcu?atxmega256d3 \
1498 mmcu?avrxmega7=mmcu?atxmega128a1 \
1499 - mmcu?avrxmega7=mmcu?atxmega128a1u
1500 + mmcu?avrxmega7=mmcu?atxmega128a1u \
1501 + mmcu?avrtiny=mmcu?attiny4 \
1502 + mmcu?avrtiny=mmcu?attiny5 \
1503 + mmcu?avrtiny=mmcu?attiny9 \
1504 + mmcu?avrtiny=mmcu?attiny10 \
1505 + mmcu?avrtiny=mmcu?attiny20 \
1506 + mmcu?avrtiny=mmcu?attiny40
1507 diff -Naurp libgcc/config/avr/lib1funcs.S libgcc/config/avr/lib1funcs.S
1508 --- libgcc/config/avr/lib1funcs.S 2012-03-28 14:34:11.000000000 +0530
1509 +++ libgcc/config/avr/lib1funcs.S 2013-01-21 18:58:03.000000000 +0530
1510 @@ -22,8 +22,13 @@ a copy of the GCC Runtime Library Except
1511 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
1512 <http://www.gnu.org/licenses/>. */
1514 +#if defined (__AVR_TINY__)
1515 +#define __zero_reg__ r17
1516 +#define __tmp_reg__ r16
1518 #define __zero_reg__ r1
1519 #define __tmp_reg__ r0
1521 #define __SREG__ 0x3f
1522 #if defined (__AVR_HAVE_SPH__)
1523 #define __SP_H__ 0x3e
1524 @@ -80,6 +85,15 @@ see the files COPYING3 and COPYING.RUNTI
1528 +.macro wsubi r_arg1, i_arg2
1529 +#if defined (__AVR_TINY__)
1530 + subi \r_arg1, lo8(\i_arg2)
1531 + sbci \r_arg1+1, hi8(\i_arg2)
1533 + sbiw \r_arg1, \i_arg2
1540 @@ -150,12 +164,12 @@ ENDF __umulqihi3
1541 Multiplication 16 x 16 without MUL
1542 *******************************************************/
1543 #if defined (L_mulhi3)
1544 -#define r_arg1L r24 /* multiplier Low */
1545 -#define r_arg1H r25 /* multiplier High */
1546 -#define r_arg2L r22 /* multiplicand Low */
1547 -#define r_arg2H r23 /* multiplicand High */
1548 +#define r_arg1L 24 /* multiplier Low */
1549 +#define r_arg1H 25 /* multiplier High */
1550 +#define r_arg2L 22 /* multiplicand Low */
1551 +#define r_arg2H 23 /* multiplicand High */
1552 #define r_resL __tmp_reg__ /* result Low */
1553 -#define r_resH r21 /* result High */
1554 +#define r_resH 21 /* result High */
1557 clr r_resH ; clear result
1558 @@ -175,7 +189,7 @@ __mulhi3_skip1:
1560 lsr r_arg1H ; gets LSB of multiplier
1564 brne __mulhi3_loop ; exit if multiplier = 0
1566 mov r_arg1H,r_resH ; result to return register
1567 @@ -230,22 +244,34 @@ ENDF __umulhisi3
1568 /*******************************************************
1569 Multiplication 32 x 32 without MUL
1570 *******************************************************/
1571 -#define r_arg1L r22 /* multiplier Low */
1572 -#define r_arg1H r23
1573 -#define r_arg1HL r24
1574 -#define r_arg1HH r25 /* multiplier High */
1576 -#define r_arg2L r18 /* multiplicand Low */
1577 -#define r_arg2H r19
1578 -#define r_arg2HL r20
1579 -#define r_arg2HH r21 /* multiplicand High */
1580 +#define r_arg1L 22 /* multiplier Low */
1582 +#define r_arg1HL 24
1583 +#define r_arg1HH 25 /* multiplier High */
1585 +#define r_arg2L 18 /* multiplicand Low */
1587 +#define r_arg2HL 20
1588 +#define r_arg2HH 21 /* multiplicand High */
1590 -#define r_resL r26 /* result Low */
1592 -#define r_resHL r30
1593 -#define r_resHH r31 /* result High */
1594 +#define r_resL 26 /* result Low */
1597 +#define r_resHH 31 /* result High */
1600 +#if defined (__AVR_TINY__)
1601 + in r26,__SP_L__ ; safe to use X, as it is r_resL/H
1603 + subi r26, lo8(-3) ; Add 3 to point past return address
1605 + push r_arg2L ; save callee saved regs
1607 + ld r_arg2L,X+ ; load from caller stack
1611 +#endif /* defined (__AVR_TINY__) */
1612 clr r_resHH ; clear result
1613 clr r_resHL ; clear result
1614 clr r_resH ; clear result
1615 @@ -268,7 +294,7 @@ __mulsi3_skip1:
1622 brne __mulsi3_loop ; exit if multiplier = 0
1624 @@ -276,6 +302,10 @@ __mulsi3_exit:
1625 mov_l r_arg1HL,r_resHL
1626 mov_h r_arg1H,r_resH
1627 mov_l r_arg1L,r_resL
1628 +#if defined (__AVR_TINY__)
1629 + pop r_arg2H ; restore callee saved regs
1631 +#endif /* defined (__AVR_TINY__) */
1635 @@ -514,9 +544,12 @@ ENDF __mulpsi3
1638 #else /* !HAVE_MUL */
1640 ;; C[0..2]: Expand Result
1641 +#if defined (__AVR_TINY__)
1645 +#endif /* defined (__AVR_TINY__) */
1649 @@ -524,6 +557,17 @@ ENDF __mulpsi3
1650 ;; Clobbers: __tmp_reg__, R18, R19, R20, R21
1653 +#if defined (__AVR_TINY__)
1656 + subi r26, lo8(-3) ; Add 3 to point past return address
1658 + push B0 ; save callee saved regs
1660 + ld B0,X+ ; load from caller stack
1663 +#endif /* defined (__AVR_TINY__) */
1667 @@ -550,6 +594,10 @@ DEFUN __mulpsi3
1671 +#if defined (__AVR_TINY__)
1674 +#endif /* (__AVR_TINY__) */
1678 @@ -618,6 +666,7 @@ ENDF __mulsqipsi3
1679 Multiplication 64 x 64
1680 *******************************************************/
1682 +#if !defined (__AVR_TINY__)
1683 #if defined (L_muldi3)
1686 @@ -855,6 +904,7 @@ ENDF __muldi3
1689 #endif /* L_muldi3 */
1690 +#endif /* !defined (__AVR_TINY__) */
1692 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1694 @@ -1027,7 +1077,7 @@ ENDF __divmodhi4
1697 #if defined (L_udivmodpsi4)
1698 -;; R24:R22 = R24:R22 udiv R20:R18
1699 +;; R24:R22 = R24:R24 udiv R20:R18
1700 ;; R20:R18 = R24:R22 umod R20:R18
1701 ;; Clobbers: R21, R25, R26
1703 @@ -1248,6 +1298,10 @@ ENDF __divmodsi4
1704 #endif /* defined (L_divmodsi4) */
1707 +/* *di routines use registers below R19 and won't work with tiny arch
1710 +#if !defined (__AVR_TINY__)
1711 /*******************************************************
1714 @@ -1665,12 +1719,15 @@ ENDF __negdi2
1718 +#endif /* !defined (__AVR_TINY__) */
1721 .section .text.libgcc.prologue, "ax", @progbits
1723 /**********************************
1724 * This is a prologue subroutine
1725 **********************************/
1726 +#if !defined (__AVR_TINY__)
1727 #if defined (L_prologue)
1729 ;; This function does not clobber T-flag; 64-bit division relies on it
1730 @@ -1776,6 +1833,7 @@ DEFUN __epilogue_restores__
1732 ENDF __epilogue_restores__
1733 #endif /* defined (L_epilogue) */
1734 +#endif /* !defined (__AVR_TINY__) */
1737 .section .fini9,"ax",@progbits
1738 @@ -1820,8 +1878,13 @@ DEFUN __tablejump__
1743 -#else /* !HAVE_LPMX */
1744 +#elif defined (__AVR_TINY__)
1745 + wsubi 30, -(__AVR_TINY_PM_BASE_ADDRESS__) ; Add PM offset to Z
1746 + ld __tmp_reg__, Z+
1747 + ld r31, Z ; Use ld instead of lpm to load Z
1748 + mov r30, __tmp_reg__
1750 +#else /* !HAVE_LPMX && !AVR_TINY */
1754 @@ -1836,6 +1899,26 @@ DEFUN __tablejump__
1756 #endif /* defined (L_tablejump) */
1758 +#if defined(__AVR_TINY__)
1760 + .section .init4,"ax",@progbits
1761 + .global __do_copy_data
1763 + ldi r18, hi8(__data_end)
1764 + ldi r26, lo8(__data_start)
1765 + ldi r27, hi8(__data_start)
1766 + ldi r30, lo8(__data_load_start + __AVR_TINY_PM_BASE_ADDRESS__)
1767 + ldi r31, hi8(__data_load_start + __AVR_TINY_PM_BASE_ADDRESS__)
1768 + rjmp .L__do_copy_data_start
1769 +.L__do_copy_data_loop:
1772 +.L__do_copy_data_start:
1773 + cpi r26, lo8(__data_end)
1775 + brne .L__do_copy_data_loop
1779 .section .init4,"ax",@progbits
1780 DEFUN __do_copy_data
1781 @@ -1901,13 +1984,14 @@ DEFUN __do_copy_data
1782 #endif /* ELPM && RAMPD */
1784 #endif /* L_copy_data */
1785 +#endif /* !defined (__AVR_TINY__) */
1787 /* __do_clear_bss is only necessary if there is anything in .bss section. */
1790 .section .init4,"ax",@progbits
1791 DEFUN __do_clear_bss
1792 - ldi r17, hi8(__bss_end)
1793 + ldi r18, hi8(__bss_end)
1794 ldi r26, lo8(__bss_start)
1795 ldi r27, hi8(__bss_start)
1796 rjmp .do_clear_bss_start
1797 @@ -1915,7 +1999,7 @@ DEFUN __do_clear_bss
1799 .do_clear_bss_start:
1800 cpi r26, lo8(__bss_end)
1803 brne .do_clear_bss_loop
1805 #endif /* L_clear_bss */
1806 @@ -1951,7 +2035,7 @@ DEFUN __do_global_ctors
1807 ldi r29, hi8(__ctors_end)
1808 rjmp .L__do_global_ctors_start
1809 .L__do_global_ctors_loop:
1815 @@ -1994,7 +2078,11 @@ DEFUN __do_global_dtors
1820 +#if defined (__AVR_TINY__)
1825 .L__do_global_dtors_start:
1826 cpi r28, lo8(__dtors_end)
1828 @@ -2005,6 +2093,7 @@ ENDF __do_global_dtors
1830 .section .text.libgcc, "ax", @progbits
1832 +#if !defined (__AVR_TINY__)
1833 #ifdef L_tablejump_elpm
1834 DEFUN __tablejump_elpm__
1835 #if defined (__AVR_HAVE_ELPMX__)
1836 @@ -2035,7 +2124,9 @@ DEFUN __tablejump_elpm__
1838 ENDF __tablejump_elpm__
1839 #endif /* defined (L_tablejump_elpm) */
1840 +#endif /* !defined (__AVR_TINY__) */
1842 +#if !defined (__AVR_TINY__)
1843 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1844 ;; Loading n bytes from Flash; n = 3,4
1845 ;; R22... = Flash[Z]
1846 @@ -2081,7 +2172,9 @@ ENDF __load_4
1847 #endif /* L_load_4 */
1849 #endif /* L_load_3 || L_load_3 */
1850 +#endif /* !defined (__AVR_TINY__) */
1852 +#if !defined (__AVR_TINY__)
1853 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1854 ;; Loading n bytes from Flash or RAM; n = 1,2,3,4
1855 ;; R22... = Flash[R21:Z] or RAM[Z] depending on R21.7
1856 @@ -2207,7 +2300,9 @@ ENDF __xload_4
1857 #endif /* L_xload_4 */
1859 #endif /* L_xload_{1|2|3|4} */
1860 +#endif /* if !defined (__AVR_TINY__) */
1862 +#if !defined (__AVR_TINY__)
1863 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1864 ;; memcopy from Address Space __pgmx to RAM
1865 ;; R23:Z = Source Address
1866 @@ -2279,6 +2374,7 @@ ENDF __movmemx_hi
1869 #endif /* L_movmemx */
1870 +#endif /* !defined (__AVR_TINY__) */
1873 .section .text.libgcc.builtins, "ax", @progbits
1874 diff -Naurp libgcc/config/avr/t-avr libgcc/config/avr/t-avr
1875 --- libgcc/config/avr/t-avr 2012-01-10 15:12:10.000000000 +0530
1876 +++ libgcc/config/avr/t-avr 2013-01-21 18:40:04.000000000 +0530
1878 LIB1ASMSRC = avr/lib1funcs.S
1883 - _mulpsi3 _mulsqipsi3 \
1893 @@ -16,19 +12,9 @@ LIB1ASMFUNCS = \
1894 _divmodpsi4 _udivmodpsi4 \
1897 - _divdi3 _udivdi3 \
1908 - _xload_1 _xload_2 _xload_3 _xload_4 \
1913 @@ -38,22 +24,52 @@ LIB1ASMFUNCS = \
1928 + _fmul _fmuls _fmulsu
1930 +# The below functions either use registers that are not present
1931 +# in tiny core, or use a different register conventions (don't save
1932 +# callee saved regs, for example)
1933 +# _mulhisi3 and variations - clobber R18, R19
1934 +# All *di funcs - use regs < R16 or expect args in regs < R20
1935 +# _prologue and _epilogue save registers < R16
1936 +# _tablejump/_tablejump_elmp - expect lpm and elpm support
1937 +# _load ad _xload variations - expect lpm and elpm support
1938 +# _movmemx - expects elpm/lpm
1940 +ifneq ($(MULTIFLAGS),-mmcu=avrtiny)
1948 + _divdi3 _udivdi3 \
1956 + _xload_1 _xload_2 _xload_3 _xload_4 \
1962 _ashldi3 _ashrdi3 _lshrdi3 _rotldi3 \
1963 _adddi3 _adddi3_s8 _subdi3 \
1964 - _cmpdi2 _cmpdi2_s8 \
1965 - _fmul _fmuls _fmulsu
1966 + _cmpdi2 _cmpdi2_s8
1969 LIB2FUNCS_EXCLUDE = \