* PATCH: AVR - Set and save/restore EIND on avr6
@ 2008-04-17 14:34 Tristan Gingold
2008-04-28 16:11 ` Ping: " Tristan Gingold
0 siblings, 1 reply; 3+ messages in thread
From: Tristan Gingold @ 2008-04-17 14:34 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 606 bytes --]
Hi,
the call_prologue doesn't work on avr6 as EIJMP is used while EIND is
not set.
This patch sets EIND on avr6 before calling __prologue_saves__, and
save/restore EIND in
interrupt/signal functions.
Tristan.
2008-04-17 Tristan Gingold <gingold@adacore.com>
* config/avr/avr.md (EIND_ADDR): Define.
(call_prologue_saves_avr6): Add.
* config/avr/avr.c (expand_prologue): On 3_BYTE_PC mcus save EIND
if interrupt or signal and use avr6 variant of prologue_saves.
(expand_epilogue): Restore EIND on 3_BYTE_PC mcus if interrupt or
signal.
(avr_file_start): Declare __EIND__ on 3_BYTE_PC mcus.
[-- Attachment #2: avr.diff --]
[-- Type: application/octet-stream, Size: 4519 bytes --]
2008-04-17 Tristan Gingold <gingold@adacore.com>
* config/avr/avr.md (EIND_ADDR): Define.
(call_prologue_saves_avr6): Add.
* config/avr/avr.c (expand_prologue): On 3_BYTE_PC mcus save EIND
if interrupt or signal and use avr6 variant of prologue_saves.
(expand_epilogue): Restore EIND on 3_BYTE_PC mcus if interrupt or
signal.
(avr_file_start): Declare __EIND__ on 3_BYTE_PC mcus.
--- config/avr/avr.md (revision 134344)
+++ config/avr/avr.md (working copy)
@@ -49,6 +49,7 @@
(SREG_ADDR 0x5F)
(RAMPZ_ADDR 0x5B)
+ (EIND_ADDR 0x5C)
(UNSPEC_STRLEN 0)
(UNSPEC_INDEX_JMP 1)
@@ -79,7 +80,7 @@
(const_string "no"))))
-;; The size of instructions in bytes.
+;; The size of instructions in words.
;; XXX may depend from "cc"
(define_attr "length" ""
@@ -2776,7 +2777,7 @@
(match_operand:HI 1 "immediate_operand" "")))
(use (reg:HI REG_X))
(clobber (reg:HI REG_Z))]
- ""
+ "!AVR_3_BYTE_PC"
"ldi r30,pm_lo8(1f)
ldi r31,pm_hi8(1f)
%~jmp __prologue_saves__+((18 - %0) * 2)
@@ -2787,6 +2788,25 @@
(const_int 5))])
(set_attr "cc" "clobber")
])
+
+(define_insn "call_prologue_saves_avr6"
+ [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
+ (match_operand:HI 0 "immediate_operand" "")
+ (set (reg:HI REG_SP) (minus:HI
+ (reg:HI REG_SP)
+ (match_operand:HI 1 "immediate_operand" "")))
+ (use (reg:HI REG_X))
+ (clobber (reg:HI REG_Z))]
+ "AVR_3_BYTE_PC"
+ "ldi r30,pm_hh8(1f)
+ out __EIND__,r30
+ ldi r31,pm_hi8(1f)
+ ldi r30,pm_lo8(1f)
+ jmp __prologue_saves__+((18 - %0) * 2)
+1:"
+ [(set_attr "length" "8")
+ (set_attr "cc" "clobber")
+ ])
; epilogue restores using library
(define_insn "epilogue_restores"
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c (revision 134344)
+++ config/avr/avr.c (working copy)
@@ -647,8 +647,8 @@
RTX_FRAME_RELATED_P (insn) = 1;
/* Push RAMPZ. */
- if(AVR_HAVE_RAMPZ
- && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
+ if (AVR_HAVE_RAMPZ
+ && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
{
insn = emit_move_insn (tmp_reg_rtx,
gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
@@ -657,6 +657,16 @@
RTX_FRAME_RELATED_P (insn) = 1;
}
+ /* Push EIND. */
+ if (AVR_3_BYTE_PC)
+ {
+ insn = emit_move_insn (tmp_reg_rtx,
+ gen_rtx_MEM (QImode, GEN_INT (EIND_ADDR)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ insn = emit_move_insn (pushbyte, tmp_reg_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
/* Clear zero reg. */
insn = emit_move_insn (zero_reg_rtx, const0_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
@@ -666,13 +676,20 @@
}
if (minimize && (frame_pointer_needed || live_seq > 6))
{
+ rtx nregs;
+ rtx spsize;
+
insn = emit_move_insn (gen_rtx_REG (HImode, REG_X),
gen_int_mode (size, HImode));
RTX_FRAME_RELATED_P (insn) = 1;
- insn =
- emit_insn (gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
- gen_int_mode (size + live_seq, HImode)));
+ nregs = gen_int_mode (live_seq, HImode);
+ spsize = gen_int_mode (size + live_seq, HImode);
+ if (AVR_3_BYTE_PC)
+ insn = gen_call_prologue_saves_avr6 (nregs, spsize);
+ else
+ insn = gen_call_prologue_saves (nregs, spsize);
+ insn = emit_insn (insn);
RTX_FRAME_RELATED_P (insn) = 1;
}
else
@@ -919,6 +936,14 @@
}
if (cfun->machine->is_interrupt || cfun->machine->is_signal)
{
+ /* Restore EIND using tmp reg as scratch. */
+ if(AVR_3_BYTE_PC)
+ {
+ emit_insn (gen_popqi (tmp_reg_rtx));
+ emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(EIND_ADDR)),
+ tmp_reg_rtx);
+ }
+
/* Restore RAMPZ using tmp reg as scratch. */
if(AVR_HAVE_RAMPZ
&& (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
@@ -4819,6 +4844,8 @@
fputs ("__SREG__ = 0x3f\n"
"__SP_H__ = 0x3e\n"
"__SP_L__ = 0x3d\n", asm_out_file);
+ if (AVR_3_BYTE_PC)
+ fputs ("__EIND__ = 0x3c\n", asm_out_file);
fputs ("__tmp_reg__ = 0\n"
"__zero_reg__ = 1\n", asm_out_file);
^ permalink raw reply [flat|nested] 3+ messages in thread
* Ping: PATCH: AVR - Set and save/restore EIND on avr6
2008-04-17 14:34 PATCH: AVR - Set and save/restore EIND on avr6 Tristan Gingold
@ 2008-04-28 16:11 ` Tristan Gingold
[not found] ` <258DDD1F44B6ED4AAFD4370847CF58D5014C9731@csomb01.corp.atmel.com>
0 siblings, 1 reply; 3+ messages in thread
From: Tristan Gingold @ 2008-04-28 16:11 UTC (permalink / raw)
To: gcc-patches
http://gcc.gnu.org/ml/gcc-patches/2008-04/msg01363.html
On Apr 17, 2008, at 2:25 PM, Tristan Gingold wrote:
> Hi,
>
> the call_prologue doesn't work on avr6 as EIJMP is used while EIND
> is not set.
> This patch sets EIND on avr6 before calling __prologue_saves__, and
> save/restore EIND in
> interrupt/signal functions.
>
> Tristan.
>
> 2008-04-17 Tristan Gingold <gingold@adacore.com>
>
> * config/avr/avr.md (EIND_ADDR): Define.
> (call_prologue_saves_avr6): Add.
> * config/avr/avr.c (expand_prologue): On 3_BYTE_PC mcus save EIND
> if interrupt or signal and use avr6 variant of prologue_saves.
> (expand_epilogue): Restore EIND on 3_BYTE_PC mcus if interrupt or
> signal.
> (avr_file_start): Declare __EIND__ on 3_BYTE_PC mcus.<avr.diff>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Ping: PATCH: AVR - Set and save/restore EIND on avr6
[not found] ` <6DD3D198500E4124B98825B7C80AF4D8@Vista>
@ 2008-04-29 11:27 ` Tristan Gingold
0 siblings, 0 replies; 3+ messages in thread
From: Tristan Gingold @ 2008-04-29 11:27 UTC (permalink / raw)
To: Anatoly Sokolov; +Cc: Eric Weddington, Andrew Hutchinson, gcc-patches
On Apr 28, 2008, at 7:44 PM, Anatoly Sokolov wrote:
> Hi.
>
> In my opinion this patch incorrect. The EIND registr should ALWAYS
> contain high (3) byte of '.trampolines' section. Your patch changes
> EIND.
Ok, I missed the indirect call case.
But we don't generate trampoline for prologue_saves:
"ldi r30,pm_lo8(1f)
ldi r31,pm_hi8(1f)
%~jmp __prologue_saves__+((18 - %0) * 2)
1:"
and as a consequence prologue_saves doesn't return at the right
address if the code in high in memory.
Should we fix this relocs ?
Tristan.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-04-29 8:33 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-04-17 14:34 PATCH: AVR - Set and save/restore EIND on avr6 Tristan Gingold
2008-04-28 16:11 ` Ping: " Tristan Gingold
[not found] ` <258DDD1F44B6ED4AAFD4370847CF58D5014C9731@csomb01.corp.atmel.com>
[not found] ` <F6E862EA-5474-43E1-97FD-ED595587121A@adacore.com>
[not found] ` <6DD3D198500E4124B98825B7C80AF4D8@Vista>
2008-04-29 11:27 ` Tristan Gingold
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).