@@ -278,7 +278,8 @@ arc64_save_callee_saves (void)
278
278
279
279
for (regno = R58_REGNUM ; regno >= R0_REGNUM ; regno -- )
280
280
{
281
- if (frame -> reg_offset [regno ] == -1 )
281
+ if (frame -> reg_offset [regno ] == -1
282
+ || (frame_pointer_needed && regno == R27_REGNUM ))
282
283
continue ;
283
284
284
285
reg = gen_rtx_REG (save_mode , regno );
@@ -688,53 +689,109 @@ arc64_modes_tieable_p (machine_mode mode1, machine_mode mode2)
688
689
return false;
689
690
}
690
691
691
- /* Print operand X (an rtx) in assembler syntax to file FILE.
692
- CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
693
- For `%' followed by punctuation, CODE is the punctuation and X is null. */
692
+ static inline bool
693
+ arc64_short_insn_p (rtx_insn * insn )
694
+ {
695
+ enum attr_iscompact iscompact ;
696
+
697
+ iscompact = get_attr_iscompact (insn );
698
+ if (iscompact == ISCOMPACT_YES )
699
+ return true;
700
+
701
+ if (iscompact == ISCOMPACT_MAYBE )
702
+ return (get_attr_length (insn ) == 2 )
703
+ || (get_attr_length (insn ) == 6 );
704
+
705
+ return false;
706
+ }
707
+
708
+ /* Print operand X (an rtx) in assembler syntax to file FILE. CODE is
709
+ a letter or dot (`z' in `%z0') or 0 if no letter was specified.
710
+ For `%' followed by punctuation, CODE is the punctuation and X is
711
+ null. Letters `acln' are reserved. The acceptable formatting
712
+ commands given by CODE are:
713
+ '0': Print a normal operand, if it's a general register,
714
+ then we assume DImode.
715
+ 'U': Load/store update or scaling indicator.
716
+ '?': Short instruction suffix.
717
+ */
694
718
695
719
static void
696
720
arc64_print_operand (FILE * file , rtx x , int code )
697
721
{
698
- switch (GET_CODE ( x ) )
722
+ switch (code )
699
723
{
700
- case REG :
701
- fputs (reg_names [REGNO (x )], file );
724
+ case '?' :
725
+ if (arc64_short_insn_p (current_output_insn ))
726
+ fputs ("_s" , file );
702
727
break ;
703
- case MEM :
704
- {
705
- rtx addr = XEXP (x , 0 );
706
- int size = GET_MODE_SIZE (GET_MODE (x ));
707
-
708
- fputc ('[' , file );
709
-
710
- switch (GET_CODE (addr ))
711
- {
712
- case PRE_INC : case POST_INC :
713
- output_address (VOIDmode ,
714
- plus_constant (Pmode , XEXP (addr , 0 ), size )); break ;
715
- case PRE_DEC : case POST_DEC :
716
- output_address (VOIDmode ,
717
- plus_constant (Pmode , XEXP (addr , 0 ), - size ));
718
- break ;
719
- case PRE_MODIFY : case POST_MODIFY :
720
- output_address (VOIDmode , XEXP (addr , 1 )); break ;
721
- case PLUS :
722
- output_address (VOIDmode , addr );
723
- break ;
724
- default :
725
- output_address (VOIDmode , addr );
726
- break ;
727
- }
728
- fputc (']' , file );
729
- break ;
730
- }
731
- /* Let output_addr_const deal with it. */
732
- default :
733
- output_addr_const (file , x );
728
+
729
+ case 'U' :
730
+ /* Output a load/store with update indicator if appropriate. */
731
+ if (!MEM_P (x ))
732
+ {
733
+ output_operand_lossage ("invalid operand for %%U code" );
734
+ return ;
735
+ }
736
+
737
+ switch (GET_CODE (XEXP (x , 0 )))
738
+ {
739
+ case PRE_INC :
740
+ case PRE_DEC :
741
+ case PRE_MODIFY :
742
+ fputs (".a" , file );
743
+ break ;
744
+
745
+ case POST_INC :
746
+ case POST_DEC :
747
+ case POST_MODIFY :
748
+ fputs (".ab" , file );
749
+ break ;
750
+
751
+ default :
752
+ break ;
753
+ }
734
754
break ;
755
+
756
+ case 0 :
757
+ if (x == NULL )
758
+ {
759
+ output_operand_lossage ("missing operand" );
760
+ return ;
761
+ }
762
+
763
+ switch (GET_CODE (x ))
764
+ {
765
+ case REG :
766
+ asm_fprintf (file , "%s" , reg_names [REGNO (x )]);
767
+ break ;
768
+
769
+ case MEM :
770
+ output_address (GET_MODE (x ), XEXP (x , 0 ));
771
+ break ;
772
+
773
+ case LABEL_REF :
774
+ case SYMBOL_REF :
775
+ output_addr_const (asm_out_file , x );
776
+ break ;
777
+
778
+ case CONST_INT :
779
+ asm_fprintf (file , "%wd" , INTVAL (x ));
780
+ break ;
781
+
782
+ default :
783
+ output_operand_lossage ("invalid operand" );
784
+ return ;
785
+ }
786
+ break ;
787
+
788
+ default :
789
+ output_operand_lossage ("invalid operand prefix '%%%c'" , code );
735
790
}
736
791
}
737
792
793
+ /* Print address 'addr' of a memory access with mode 'mode'. */
794
+
738
795
static void
739
796
arc64_print_operand_address (FILE * file , machine_mode mode , rtx addr )
740
797
{
@@ -745,9 +802,6 @@ arc64_print_operand_address (FILE *file , machine_mode mode, rtx addr)
745
802
case REG :
746
803
fputs (reg_names [REGNO (addr )], file );
747
804
break ;
748
- case SYMBOL_REF :
749
- output_addr_const (file , addr );
750
- break ;
751
805
case PLUS :
752
806
if (GET_CODE (XEXP (addr , 0 )) == MULT )
753
807
index = XEXP (XEXP (addr , 0 ), 0 ), base = XEXP (addr , 1 );
@@ -777,18 +831,34 @@ arc64_print_operand_address (FILE *file , machine_mode mode, rtx addr)
777
831
778
832
break ;
779
833
}
780
- case PRE_INC :
781
- case PRE_DEC :
782
- /* We shouldn't get here as we've lost the mode of the memory object
783
- (which says how much to inc/dec by. */
784
- gcc_unreachable ( );
834
+ case PRE_INC :
835
+ case POST_INC :
836
+ output_address ( VOIDmode ,
837
+ plus_constant ( Pmode , XEXP ( addr , 0 ),
838
+ GET_MODE_SIZE ( mode )) );
785
839
break ;
840
+ case PRE_DEC :
841
+ case POST_DEC :
842
+ output_address (VOIDmode ,
843
+ plus_constant (Pmode , XEXP (addr , 0 ),
844
+ - GET_MODE_SIZE (mode )));
845
+ break ;
846
+ case SYMBOL_REF :
786
847
default :
787
848
output_addr_const (file , addr );
788
849
break ;
789
850
}
790
851
}
791
852
853
+ /* Target hook for indicating whether a punctuation character for
854
+ TARGET_PRINT_OPERAND is valid. */
855
+
856
+ static bool
857
+ arc64_print_operand_punct_valid_p (unsigned char code )
858
+ {
859
+ return (code == '?' );
860
+ }
861
+
792
862
/*
793
863
Global functions.
794
864
*/
@@ -1177,6 +1247,9 @@ arc64_expand_epilogue (bool sibcall_p)
1177
1247
#undef TARGET_PRINT_OPERAND_ADDRESS
1178
1248
#define TARGET_PRINT_OPERAND_ADDRESS arc64_print_operand_address
1179
1249
1250
+ #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
1251
+ #define TARGET_PRINT_OPERAND_PUNCT_VALID_P arc64_print_operand_punct_valid_p
1252
+
1180
1253
struct gcc_target targetm = TARGET_INITIALIZER ;
1181
1254
1182
1255
#include "gt-arc64.h"
0 commit comments