]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
avr.c (TARGET_EXCEPT_UNWIND_INFO): New.
authorRichard Henderson <rth@redhat.com>
Tue, 22 Mar 2011 16:02:51 +0000 (09:02 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 22 Mar 2011 16:02:51 +0000 (09:02 -0700)
* config/avr/avr.c (TARGET_EXCEPT_UNWIND_INFO): New.
(avr_incoming_return_addr_rtx): New.
(emit_push_byte): New.
(expand_prologue): Use it.  Remove incorrect dwarf annotation for
SREG, RAMPZ, zero register.  Push frame pointer by bytes.  Add dwarf
annotation for __prologue_saves__.  Fixup dwarf annotation for CFA.
(emit_pop_byte): New.
(expand_epilogue): Use it.  Pop frame pointer by bytes.
* config/avr/avr.h (FRAME_POINTER_CFA_OFFSET): Remove.
(INCOMING_RETURN_ADDR_RTX): New.
(INCOMING_FRAME_SP_OFFSET): New.
(ARG_POINTER_CFA_OFFSET): New.
* config/avr/avr.md (*pushqi): Fix mode of auto-inc.
(*pushhi, *pushsi, *pushsf, popqi): Likewise.
(pophi): Remove.

From-SVN: r171295

gcc/ChangeLog
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c
gcc/config/avr/avr.h
gcc/config/avr/avr.md

index 4413aa625aa1606947428967de2542b92ad9bb43..396c8be7a84b8db0185f488bff90726c8fbad398 100644 (file)
@@ -1,3 +1,21 @@
+2011-03-22  Richard Henderson  <rth@redhat.com>
+
+       * config/avr/avr.c (TARGET_EXCEPT_UNWIND_INFO): New.
+       (avr_incoming_return_addr_rtx): New.
+       (emit_push_byte): New.
+       (expand_prologue): Use it.  Remove incorrect dwarf annotation for
+       SREG, RAMPZ, zero register.  Push frame pointer by bytes.  Add dwarf
+       annotation for __prologue_saves__.  Fixup dwarf annotation for CFA.
+       (emit_pop_byte): New.
+       (expand_epilogue): Use it.  Pop frame pointer by bytes.
+       * config/avr/avr.h (FRAME_POINTER_CFA_OFFSET): Remove.
+       (INCOMING_RETURN_ADDR_RTX): New.
+       (INCOMING_FRAME_SP_OFFSET): New.
+       (ARG_POINTER_CFA_OFFSET): New.
+       * config/avr/avr.md (*pushqi): Fix mode of auto-inc.
+       (*pushhi, *pushsi, *pushsf, popqi): Likewise.
+       (pophi): Remove.
+
 2011-03-22  Nathan Froyd  <froydnj@codesourcery.com>
 
        * tree.c (build_call_1): New function.
index 67e915a569e819175808c4a27448042fdd395fb0..3882429adb102072a31a14d1a8c605e596c19c3a 100644 (file)
@@ -108,6 +108,7 @@ extern RTX_CODE avr_normalize_condition (RTX_CODE condition);
 extern int compare_eq_p (rtx insn);
 extern void out_shift_with_cnt (const char *templ, rtx insn,
                                rtx operands[], int *len, int t_len);
+extern rtx avr_incoming_return_addr_rtx (void);
 #endif /* RTX_CODE */
 
 #ifdef HAVE_MACHINE_MODES
index f9211886be5898f4d7e0eaadb2ec70cee3232e68..9a32b973c9a0f27eb3b48a7100adb3aed6e7028c 100644 (file)
@@ -246,6 +246,9 @@ static const struct default_options avr_option_optimization_table[] =
 #undef TARGET_HELP
 #define TARGET_HELP avr_help
 
+#undef TARGET_EXCEPT_UNWIND_INFO
+#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 static void
@@ -597,6 +600,35 @@ get_sequence_length (rtx insns)
   return length;
 }
 
+/*  Implement INCOMING_RETURN_ADDR_RTX.  */
+
+rtx
+avr_incoming_return_addr_rtx (void)
+{
+  /* The return address is at the top of the stack.  Note that the push
+     was via post-decrement, which means the actual address is off by one.  */
+  return gen_frame_mem (HImode, plus_constant (stack_pointer_rtx, 1));
+}
+
+/*  Helper for expand_prologue.  Emit a push of a byte register.  */
+
+static void
+emit_push_byte (unsigned regno, bool frame_related_p)
+{
+  rtx mem, reg, insn;
+
+  mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
+  mem = gen_frame_mem (QImode, mem);
+  reg = gen_rtx_REG (QImode, regno);
+
+  insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
+  if (frame_related_p)
+    RTX_FRAME_RELATED_P (insn) = 1;
+
+  cfun->machine->stack_usage++;
+}
+
+
 /*  Output function prologue.  */
 
 void
@@ -606,11 +638,6 @@ expand_prologue (void)
   HARD_REG_SET set;
   int minimize;
   HOST_WIDE_INT size = get_frame_size();
-  /* Define templates for push instructions.  */
-  rtx pushbyte = gen_rtx_MEM (QImode,
-                  gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
-  rtx pushword = gen_rtx_MEM (HImode,
-                  gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
   rtx insn;
   
   /* Init cfun->machine.  */
@@ -638,46 +665,34 @@ expand_prologue (void)
 
   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
     {
+      /* Enable interrupts.  */
       if (cfun->machine->is_interrupt)
-        {
-          /* Enable interrupts.  */
-          insn = emit_insn (gen_enable_interrupt ());
-          RTX_FRAME_RELATED_P (insn) = 1;
-        }
+       emit_insn (gen_enable_interrupt ());
        
       /* Push zero reg.  */
-      insn = emit_move_insn (pushbyte, zero_reg_rtx);
-      RTX_FRAME_RELATED_P (insn) = 1;
-      cfun->machine->stack_usage++;
+      emit_push_byte (ZERO_REGNO, true);
 
       /* Push tmp reg.  */
-      insn = emit_move_insn (pushbyte, tmp_reg_rtx);
-      RTX_FRAME_RELATED_P (insn) = 1;
-      cfun->machine->stack_usage++;
+      emit_push_byte (TMP_REGNO, true);
 
       /* Push SREG.  */
-      insn = emit_move_insn (tmp_reg_rtx, 
-                             gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
-      RTX_FRAME_RELATED_P (insn) = 1;
-      insn = emit_move_insn (pushbyte, tmp_reg_rtx);
-      RTX_FRAME_RELATED_P (insn) = 1;
-      cfun->machine->stack_usage++;
+      /* ??? There's no dwarf2 column reserved for SREG.  */
+      emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
+      emit_push_byte (TMP_REGNO, false);
 
       /* Push RAMPZ.  */
-      if(AVR_HAVE_RAMPZ 
-         && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
+      /* ??? There's no dwarf2 column reserved for RAMPZ.  */
+      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)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-          insn = emit_move_insn (pushbyte, tmp_reg_rtx);
-          RTX_FRAME_RELATED_P (insn) = 1;
-          cfun->machine->stack_usage++;
+          emit_move_insn (tmp_reg_rtx,
+                         gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
+         emit_push_byte (TMP_REGNO, false);
         }
        
       /* Clear zero reg.  */
-      insn = emit_move_insn (zero_reg_rtx, const0_rtx);
-      RTX_FRAME_RELATED_P (insn) = 1;
+      emit_move_insn (zero_reg_rtx, const0_rtx);
 
       /* Prevent any attempt to delete the setting of ZERO_REG!  */
       emit_use (zero_reg_rtx);
@@ -686,37 +701,63 @@ expand_prologue (void)
                   || (AVR_2_BYTE_PC && live_seq > 6)
                   || live_seq > 7)) 
     {
-      insn = emit_move_insn (gen_rtx_REG (HImode, REG_X), 
-                             gen_int_mode (size, HImode));
-      RTX_FRAME_RELATED_P (insn) = 1;
+      int first_reg, reg, offset;
+
+      emit_move_insn (gen_rtx_REG (HImode, REG_X), 
+                      gen_int_mode (size, HImode));
 
-      insn = 
-        emit_insn (gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
-                                           gen_int_mode (size + live_seq, HImode)));
+      insn = emit_insn (gen_call_prologue_saves
+                       (gen_int_mode (live_seq, HImode),
+                        gen_int_mode (size + live_seq, HImode)));
       RTX_FRAME_RELATED_P (insn) = 1;
+
+      /* Describe the effect of the unspec_volatile call to prologue_saves.
+        Note that this formulation assumes that add_reg_note pushes the
+        notes to the front.  Thus we build them in the reverse order of
+        how we want dwarf2out to process them.  */
+
+      /* The function does always set frame_pointer_rtx, but whether that
+        is going to be permanent in the function is frame_pointer_needed.  */
+      add_reg_note (insn, REG_CFA_ADJUST_CFA,
+                   gen_rtx_SET (VOIDmode,
+                                (frame_pointer_needed
+                                 ? frame_pointer_rtx : stack_pointer_rtx),
+                                plus_constant (stack_pointer_rtx,
+                                               -(size + live_seq))));
+
+      /* Note that live_seq always contains r28+r29, but the other
+        registers to be saved are all below 18.  */
+      first_reg = 18 - (live_seq - 2);
+
+      for (reg = 29, offset = -live_seq + 1;
+          reg >= first_reg;
+          reg = (reg == 28 ? 17 : reg - 1), ++offset)
+       {
+         rtx m, r;
+
+         m = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, offset));
+         r = gen_rtx_REG (QImode, reg);
+         add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
+       }
+
       cfun->machine->stack_usage += size + live_seq;
     }
   else
     {
       int reg;
       for (reg = 0; reg < 32; ++reg)
-        {
-          if (TEST_HARD_REG_BIT (set, reg))
-            {
-              /* Emit push of register to save.  */
-              insn=emit_move_insn (pushbyte, gen_rtx_REG (QImode, reg));
-              RTX_FRAME_RELATED_P (insn) = 1;
-              cfun->machine->stack_usage++;
-            }
-        }
+        if (TEST_HARD_REG_BIT (set, reg))
+         emit_push_byte (reg, true);
+
       if (frame_pointer_needed)
         {
          if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
            {
-              /* Push frame pointer.  */
-             insn = emit_move_insn (pushword, frame_pointer_rtx);
-              RTX_FRAME_RELATED_P (insn) = 1;
-             cfun->machine->stack_usage += 2;
+              /* Push frame pointer.  Always be consistent about the
+                ordering of pushes -- epilogue_restores expects the
+                register pair to be pushed low byte first.  */
+             emit_push_byte (REG_Y, true);
+             emit_push_byte (REG_Y + 1, true);
            }
 
           if (!size)
@@ -739,13 +780,12 @@ expand_prologue (void)
               is selected.  */
               rtx myfp;
              rtx fp_plus_insns; 
-             rtx sp_plus_insns = NULL_RTX;
 
               if (AVR_HAVE_8BIT_SP)
                 {
-                  /* The high byte (r29) doesn't change - prefer 'subi' (1 cycle)
-                     over 'sbiw' (2 cycles, same size).  */
-                  myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
+                  /* The high byte (r29) doesn't change.  Prefer 'subi'
+                    (1 cycle) over 'sbiw' (2 cycles, same size).  */
+                  myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
                 }
               else 
                 {
@@ -756,41 +796,43 @@ expand_prologue (void)
              /* Method 1-Adjust frame pointer.  */
              start_sequence ();
 
-              insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
-              RTX_FRAME_RELATED_P (insn) = 1;
+             /* Normally the dwarf2out frame-related-expr interpreter does
+                not expect to have the CFA change once the frame pointer is
+                set up.  Thus we avoid marking the move insn below and
+                instead indicate that the entire operation is complete after
+                the frame pointer subtraction is done.  */
 
-              insn = 
-               emit_move_insn (myfp,
-                               gen_rtx_PLUS (GET_MODE(myfp), myfp, 
-                                             gen_int_mode (-size, 
-                                                           GET_MODE(myfp))));
-              RTX_FRAME_RELATED_P (insn) = 1;
+              emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
 
-             /* Copy to stack pointer.  */
+              insn = emit_move_insn (myfp, plus_constant (myfp, -size));
+              RTX_FRAME_RELATED_P (insn) = 1;
+             add_reg_note (insn, REG_CFA_ADJUST_CFA,
+                           gen_rtx_SET (VOIDmode, frame_pointer_rtx,
+                                        plus_constant (stack_pointer_rtx,
+                                                       -size)));
+
+             /* Copy to stack pointer.  Note that since we've already
+                changed the CFA to the frame pointer this operation
+                need not be annotated at all.  */
              if (AVR_HAVE_8BIT_SP)
                {
-                 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
-                 RTX_FRAME_RELATED_P (insn) = 1;
+                 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
                }
              else if (TARGET_NO_INTERRUPTS 
                       || cfun->machine->is_signal
                       || cfun->machine->is_OS_main)
                {
-                 insn = 
-                   emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
-                                                      frame_pointer_rtx));
-                 RTX_FRAME_RELATED_P (insn) = 1;               
+                 emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
+                                                    frame_pointer_rtx));
                }
              else if (cfun->machine->is_interrupt)
                {
-                 insn = emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
-                                                          frame_pointer_rtx));
-                 RTX_FRAME_RELATED_P (insn) = 1;
+                 emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
+                                                   frame_pointer_rtx));
                }
              else
                {
-                 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
-                 RTX_FRAME_RELATED_P (insn) = 1;
+                 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
                }
 
              fp_plus_insns = get_insns ();
@@ -799,30 +841,30 @@ expand_prologue (void)
              /* Method 2-Adjust Stack pointer.  */
               if (size <= 6)
                 {
+                 rtx sp_plus_insns;
+
                  start_sequence ();
 
-                 insn = 
-                   emit_move_insn (stack_pointer_rtx,
-                                   gen_rtx_PLUS (HImode, 
-                                                 stack_pointer_rtx, 
-                                                 gen_int_mode (-size, 
-                                                               HImode)));
+                 insn = plus_constant (stack_pointer_rtx, -size);
+                 insn = emit_move_insn (stack_pointer_rtx, insn);
                  RTX_FRAME_RELATED_P (insn) = 1;
                  
-                 insn = 
-                   emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+                 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
                  RTX_FRAME_RELATED_P (insn) = 1;
 
                  sp_plus_insns = get_insns ();
                  end_sequence ();
-                }
 
-              /* Use shortest method.  */
-              if (size <= 6 && (get_sequence_length (sp_plus_insns) 
-                                < get_sequence_length (fp_plus_insns)))
-               emit_insn (sp_plus_insns);
-              else
+                 /* Use shortest method.  */
+                 if (get_sequence_length (sp_plus_insns) 
+                     < get_sequence_length (fp_plus_insns))
+                   emit_insn (sp_plus_insns);
+                 else
+                   emit_insn (fp_plus_insns);
+                }
+             else
                emit_insn (fp_plus_insns);
+
              cfun->machine->stack_usage += size;
             }
         }
@@ -876,6 +918,20 @@ avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
   return 0;
 }
 
+/*  Helper for expand_epilogue.  Emit a pop of a byte register.  */
+
+static void
+emit_pop_byte (unsigned regno)
+{
+  rtx mem, reg;
+
+  mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
+  mem = gen_frame_mem (QImode, mem);
+  reg = gen_rtx_REG (QImode, regno);
+
+  emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
+}
+
 /*  Output RTL epilogue.  */
 
 void
@@ -928,13 +984,12 @@ expand_epilogue (void)
               /* Try two methods to adjust stack and select shortest.  */
              rtx myfp;
              rtx fp_plus_insns;
-             rtx sp_plus_insns = NULL_RTX;
-             
+
              if (AVR_HAVE_8BIT_SP)
                 {
                   /* The high byte (r29) doesn't change - prefer 'subi' 
                      (1 cycle) over 'sbiw' (2 cycles, same size).  */
-                  myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
+                  myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
                 }
               else 
                 {
@@ -945,10 +1000,7 @@ expand_epilogue (void)
               /* Method 1-Adjust frame pointer.  */
              start_sequence ();
 
-             emit_move_insn (myfp,
-                             gen_rtx_PLUS (GET_MODE (myfp), myfp,
-                                           gen_int_mode (size, 
-                                                         GET_MODE(myfp))));
+             emit_move_insn (myfp, plus_constant (myfp, size));
 
              /* Copy to stack pointer.  */
              if (AVR_HAVE_8BIT_SP)
@@ -977,58 +1029,63 @@ expand_epilogue (void)
               /* Method 2-Adjust Stack pointer.  */
               if (size <= 5)
                 {
+                 rtx sp_plus_insns;
+
                  start_sequence ();
 
                  emit_move_insn (stack_pointer_rtx,
-                                 gen_rtx_PLUS (HImode, stack_pointer_rtx,
-                                               gen_int_mode (size, 
-                                                             HImode)));
+                                 plus_constant (stack_pointer_rtx, size));
 
                  sp_plus_insns = get_insns ();
                  end_sequence ();
-                }
 
-              /* Use shortest method.  */
-              if (size <= 5 && (get_sequence_length (sp_plus_insns) 
-                                < get_sequence_length (fp_plus_insns)))
-               emit_insn (sp_plus_insns);
-              else
+                 /* Use shortest method.  */
+                 if (get_sequence_length (sp_plus_insns) 
+                     < get_sequence_length (fp_plus_insns))
+                   emit_insn (sp_plus_insns);
+                 else
+                   emit_insn (fp_plus_insns);
+                }
+             else
                emit_insn (fp_plus_insns);
             }
          if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
            {
-              /* Restore previous frame_pointer.  */
-             emit_insn (gen_pophi (frame_pointer_rtx));
+              /* Restore previous frame_pointer.  See expand_prologue for
+                rationale for not using pophi.  */
+             emit_pop_byte (REG_Y + 1);
+             emit_pop_byte (REG_Y);
            }
        }
+
       /* Restore used registers.  */
       for (reg = 31; reg >= 0; --reg)
-        {
-          if (TEST_HARD_REG_BIT (set, reg))
-              emit_insn (gen_popqi (gen_rtx_REG (QImode, reg)));
-        }
+        if (TEST_HARD_REG_BIT (set, reg))
+          emit_pop_byte (reg);
+
       if (cfun->machine->is_interrupt || cfun->machine->is_signal)
         {
           /* 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)))
+         if (AVR_HAVE_RAMPZ 
+              && TEST_HARD_REG_BIT (set, REG_Z)
+             && TEST_HARD_REG_BIT (set, REG_Z + 1))
             {
-             emit_insn (gen_popqi (tmp_reg_rtx));
-             emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(RAMPZ_ADDR)), 
+             emit_pop_byte (TMP_REGNO);
+             emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)), 
                              tmp_reg_rtx);
            }
 
           /* Restore SREG using tmp reg as scratch.  */
-          emit_insn (gen_popqi (tmp_reg_rtx));
+          emit_pop_byte (TMP_REGNO);
       
-          emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)), 
+          emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)), 
                          tmp_reg_rtx);
 
           /* Restore tmp REG.  */
-          emit_insn (gen_popqi (tmp_reg_rtx));
+          emit_pop_byte (TMP_REGNO);
 
           /* Restore zero REG.  */
-          emit_insn (gen_popqi (zero_reg_rtx));
+          emit_pop_byte (ZERO_REGNO);
         }
 
       emit_jump_insn (gen_return ());
index 146ab6793dee2367c8702080d6ed52ff0ff47e74..bd18aedc0f47159352e1d984bc009d0f7e27f8bd 100644 (file)
@@ -351,9 +351,6 @@ enum reg_class {
 
 #define STATIC_CHAIN_REGNUM 2
 
-/* Offset from the frame pointer register value to the top of the stack.  */
-#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0
-
 #define ELIMINABLE_REGS {                                      \
       {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM},              \
        {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}            \
@@ -794,6 +791,13 @@ mmcu=*:-mmcu=%*}"
 
 #define OBJECT_FORMAT_ELF
 
+#define INCOMING_RETURN_ADDR_RTX   avr_incoming_return_addr_rtx ()
+#define INCOMING_FRAME_SP_OFFSET   (AVR_3_BYTE_PC ? 3 : 2)
+
+/* The caller's stack pointer value immediately before the call
+   is one byte below the first argument.  */
+#define ARG_POINTER_CFA_OFFSET(FNDECL)  -1
+
 #define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
   avr_hard_regno_rename_ok (OLD_REG, NEW_REG)
 
index b9e92f4a253e0513f30a23feeb776a79e4a66ade..0fdee391022d28777e951971240af40a0324a2eb 100644 (file)
 
 
 (define_insn "*pushqi"
-  [(set (mem:QI (post_dec (reg:HI REG_SP)))
+  [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
         (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
   ""
   "@
        push __zero_reg__"
   [(set_attr "length" "1,1")])
 
-
 (define_insn "*pushhi"
-  [(set (mem:HI (post_dec (reg:HI REG_SP)))
+  [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
         (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
   ""
   "@
   [(set_attr "length" "2,2")])
 
 (define_insn "*pushsi"
-  [(set (mem:SI (post_dec (reg:HI REG_SP)))
+  [(set (mem:SI (post_dec:HI (reg:HI REG_SP)))
         (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
   ""
   "@
   [(set_attr "length" "4,4")])
 
 (define_insn "*pushsf"
-  [(set (mem:SF (post_dec (reg:HI REG_SP)))
+  [(set (mem:SF (post_dec:HI (reg:HI REG_SP)))
         (match_operand:SF 0 "register_operand" "r"))]
   ""
   "push %D0
 
 (define_insn "popqi"
   [(set (match_operand:QI 0 "register_operand" "=r")
-        (mem:QI (post_inc (reg:HI REG_SP))))]
+        (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
   ""
   "pop %0"
   [(set_attr "cc" "none")
    (set_attr "length" "1")])
 
-(define_insn "pophi"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-        (mem:HI (post_inc (reg:HI REG_SP))))]
-  ""
-  "pop %A0\;pop %B0"
-  [(set_attr "cc" "none")
-   (set_attr "length" "2")])
-
 ;; Enable Interrupts
 (define_insn "enable_interrupt"
   [(unspec [(const_int 0)] UNSPEC_SEI)]