Skip to content

Commit 3679147

Browse files
clazissartemiy-volkov
authored andcommitted
[ARCx] Update print_operand and print_operand_address
1 parent e2dd89c commit 3679147

File tree

3 files changed

+190
-105
lines changed

3 files changed

+190
-105
lines changed

gcc/config/arc64/arc64.c

Lines changed: 119 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ arc64_save_callee_saves (void)
278278

279279
for (regno = R58_REGNUM; regno >= R0_REGNUM; regno--)
280280
{
281-
if (frame->reg_offset[regno] == -1)
281+
if (frame->reg_offset[regno] == -1
282+
|| (frame_pointer_needed && regno == R27_REGNUM))
282283
continue;
283284

284285
reg = gen_rtx_REG (save_mode, regno);
@@ -688,53 +689,109 @@ arc64_modes_tieable_p (machine_mode mode1, machine_mode mode2)
688689
return false;
689690
}
690691

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+
*/
694718

695719
static void
696720
arc64_print_operand (FILE *file, rtx x, int code)
697721
{
698-
switch (GET_CODE (x))
722+
switch (code)
699723
{
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);
702727
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+
}
734754
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);
735790
}
736791
}
737792

793+
/* Print address 'addr' of a memory access with mode 'mode'. */
794+
738795
static void
739796
arc64_print_operand_address (FILE *file , machine_mode mode, rtx addr)
740797
{
@@ -745,9 +802,6 @@ arc64_print_operand_address (FILE *file , machine_mode mode, rtx addr)
745802
case REG :
746803
fputs (reg_names[REGNO (addr)], file);
747804
break;
748-
case SYMBOL_REF:
749-
output_addr_const (file, addr);
750-
break;
751805
case PLUS :
752806
if (GET_CODE (XEXP (addr, 0)) == MULT)
753807
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)
777831

778832
break;
779833
}
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)));
785839
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:
786847
default :
787848
output_addr_const (file, addr);
788849
break;
789850
}
790851
}
791852

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+
792862
/*
793863
Global functions.
794864
*/
@@ -1177,6 +1247,9 @@ arc64_expand_epilogue (bool sibcall_p)
11771247
#undef TARGET_PRINT_OPERAND_ADDRESS
11781248
#define TARGET_PRINT_OPERAND_ADDRESS arc64_print_operand_address
11791249

1250+
#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
1251+
#define TARGET_PRINT_OPERAND_PUNCT_VALID_P arc64_print_operand_punct_valid_p
1252+
11801253
struct gcc_target targetm = TARGET_INITIALIZER;
11811254

11821255
#include "gt-arc64.h"

gcc/config/arc64/arc64.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@
8181
aligned. */
8282
#define LOCAL_ALIGNMENT(EXP, ALIGN) \
8383
ARC64_EXPAND_ALIGNMENT (!flag_conserve_stack, EXP, ALIGN)
84+
85+
/* Set this nonzero if move instructions will actually fail to work
86+
when given unaligned data. */
8487
#define STRICT_ALIGNMENT 1
8588

8689
/* Layout of Source Language Data Types. */
@@ -430,10 +433,6 @@ extern const enum reg_class arc64_regno_to_regclass[];
430433
end at the end of the line. */
431434
#define ASM_COMMENT_START "#"
432435

433-
/* To be used fot "U" options of asm_fprintf. */
434-
#undef USER_LABEL_PREFIX
435-
#define USER_LABEL_PREFIX "@"
436-
437436
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
438437
fprintf(FILE, "\t.align\t%d\n", (int)LOG)
439438

@@ -447,6 +446,13 @@ extern const enum reg_class arc64_regno_to_regclass[];
447446
#undef ASM_APP_OFF
448447
#define ASM_APP_OFF ""
449448

449+
#undef ASM_OUTPUT_LABELREF
450+
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
451+
do { \
452+
fputs ("@", (FILE)); \
453+
fputs ((NAME), (FILE)); \
454+
} while (0)
455+
450456
/* Section selection. */
451457

452458
/* Globalizing directive for a label. */

0 commit comments

Comments
 (0)