Commit 975ab131 by Michael Hayes Committed by Michael Hayes

c4x.h: Tidy up comments.

	* config/c4x.h: Tidy up comments.
	* config/c4x.c: Likewise.

From-SVN: r31292
parent e746974d
2000-01-09 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* config/c4x.h: Tidy up comments.
* config/c4x.c: Likewise.
Sun Jan 9 01:02:55 EST 2000 John Wehle (john@feith.com) Sun Jan 9 01:02:55 EST 2000 John Wehle (john@feith.com)
* fold-const.c (lshift_double, rshift_double): Handle * fold-const.c (lshift_double, rshift_double): Handle
......
...@@ -57,76 +57,76 @@ static char *float_reg_names[] = FLOAT_REGISTER_NAMES; ...@@ -57,76 +57,76 @@ static char *float_reg_names[] = FLOAT_REGISTER_NAMES;
enum reg_class c4x_regclass_map[FIRST_PSEUDO_REGISTER] = enum reg_class c4x_regclass_map[FIRST_PSEUDO_REGISTER] =
{ {
/* Reg Modes Saved */ /* Reg Modes Saved. */
R0R1_REGS, /* R0 QI, QF, HF No */ R0R1_REGS, /* R0 QI, QF, HF No. */
R0R1_REGS, /* R1 QI, QF, HF No */ R0R1_REGS, /* R1 QI, QF, HF No. */
R2R3_REGS, /* R2 QI, QF, HF No */ R2R3_REGS, /* R2 QI, QF, HF No. */
R2R3_REGS, /* R3 QI, QF, HF No */ R2R3_REGS, /* R3 QI, QF, HF No. */
EXT_LOW_REGS, /* R4 QI, QF, HF QI */ EXT_LOW_REGS, /* R4 QI, QF, HF QI. */
EXT_LOW_REGS, /* R5 QI, QF, HF QI */ EXT_LOW_REGS, /* R5 QI, QF, HF QI. */
EXT_LOW_REGS, /* R6 QI, QF, HF QF */ EXT_LOW_REGS, /* R6 QI, QF, HF QF. */
EXT_LOW_REGS, /* R7 QI, QF, HF QF */ EXT_LOW_REGS, /* R7 QI, QF, HF QF. */
ADDR_REGS, /* AR0 QI No */ ADDR_REGS, /* AR0 QI No. */
ADDR_REGS, /* AR1 QI No */ ADDR_REGS, /* AR1 QI No. */
ADDR_REGS, /* AR2 QI No */ ADDR_REGS, /* AR2 QI No. */
ADDR_REGS, /* AR3 QI QI */ ADDR_REGS, /* AR3 QI QI. */
ADDR_REGS, /* AR4 QI QI */ ADDR_REGS, /* AR4 QI QI. */
ADDR_REGS, /* AR5 QI QI */ ADDR_REGS, /* AR5 QI QI. */
ADDR_REGS, /* AR6 QI QI */ ADDR_REGS, /* AR6 QI QI. */
ADDR_REGS, /* AR7 QI QI */ ADDR_REGS, /* AR7 QI QI. */
DP_REG, /* DP QI No */ DP_REG, /* DP QI No. */
INDEX_REGS, /* IR0 QI No */ INDEX_REGS, /* IR0 QI No. */
INDEX_REGS, /* IR1 QI No */ INDEX_REGS, /* IR1 QI No. */
BK_REG, /* BK QI QI */ BK_REG, /* BK QI QI. */
SP_REG, /* SP QI No */ SP_REG, /* SP QI No. */
ST_REG, /* ST CC No */ ST_REG, /* ST CC No. */
NO_REGS, /* DIE/IE No */ NO_REGS, /* DIE/IE No. */
NO_REGS, /* IIE/IF No */ NO_REGS, /* IIE/IF No. */
NO_REGS, /* IIF/IOF No */ NO_REGS, /* IIF/IOF No. */
INT_REGS, /* RS QI No */ INT_REGS, /* RS QI No. */
INT_REGS, /* RE QI No */ INT_REGS, /* RE QI No. */
RC_REG, /* RC QI No */ RC_REG, /* RC QI No. */
EXT_REGS, /* R8 QI, QF, HF QI */ EXT_REGS, /* R8 QI, QF, HF QI. */
EXT_REGS, /* R9 QI, QF, HF No */ EXT_REGS, /* R9 QI, QF, HF No. */
EXT_REGS, /* R10 QI, QF, HF No */ EXT_REGS, /* R10 QI, QF, HF No. */
EXT_REGS, /* R11 QI, QF, HF No */ EXT_REGS, /* R11 QI, QF, HF No. */
}; };
enum machine_mode c4x_caller_save_map[FIRST_PSEUDO_REGISTER] = enum machine_mode c4x_caller_save_map[FIRST_PSEUDO_REGISTER] =
{ {
/* Reg Modes Saved */ /* Reg Modes Saved. */
HFmode, /* R0 QI, QF, HF No */ HFmode, /* R0 QI, QF, HF No. */
HFmode, /* R1 QI, QF, HF No */ HFmode, /* R1 QI, QF, HF No. */
HFmode, /* R2 QI, QF, HF No */ HFmode, /* R2 QI, QF, HF No. */
HFmode, /* R3 QI, QF, HF No */ HFmode, /* R3 QI, QF, HF No. */
QFmode, /* R4 QI, QF, HF QI */ QFmode, /* R4 QI, QF, HF QI. */
QFmode, /* R5 QI, QF, HF QI */ QFmode, /* R5 QI, QF, HF QI. */
QImode, /* R6 QI, QF, HF QF */ QImode, /* R6 QI, QF, HF QF. */
QImode, /* R7 QI, QF, HF QF */ QImode, /* R7 QI, QF, HF QF. */
QImode, /* AR0 QI No */ QImode, /* AR0 QI No. */
QImode, /* AR1 QI No */ QImode, /* AR1 QI No. */
QImode, /* AR2 QI No */ QImode, /* AR2 QI No. */
QImode, /* AR3 QI QI */ QImode, /* AR3 QI QI. */
QImode, /* AR4 QI QI */ QImode, /* AR4 QI QI. */
QImode, /* AR5 QI QI */ QImode, /* AR5 QI QI. */
QImode, /* AR6 QI QI */ QImode, /* AR6 QI QI. */
QImode, /* AR7 QI QI */ QImode, /* AR7 QI QI. */
VOIDmode, /* DP QI No */ VOIDmode, /* DP QI No. */
QImode, /* IR0 QI No */ QImode, /* IR0 QI No. */
QImode, /* IR1 QI No */ QImode, /* IR1 QI No. */
QImode, /* BK QI QI */ QImode, /* BK QI QI. */
VOIDmode, /* SP QI No */ VOIDmode, /* SP QI No. */
VOIDmode, /* ST CC No */ VOIDmode, /* ST CC No. */
VOIDmode, /* DIE/IE No */ VOIDmode, /* DIE/IE No. */
VOIDmode, /* IIE/IF No */ VOIDmode, /* IIE/IF No. */
VOIDmode, /* IIF/IOF No */ VOIDmode, /* IIF/IOF No. */
QImode, /* RS QI No */ QImode, /* RS QI No. */
QImode, /* RE QI No */ QImode, /* RE QI No. */
VOIDmode, /* RC QI No */ VOIDmode, /* RC QI No. */
QFmode, /* R8 QI, QF, HF QI */ QFmode, /* R8 QI, QF, HF QI. */
HFmode, /* R9 QI, QF, HF No */ HFmode, /* R9 QI, QF, HF No. */
HFmode, /* R10 QI, QF, HF No */ HFmode, /* R10 QI, QF, HF No. */
HFmode, /* R11 QI, QF, HF No */ HFmode, /* R11 QI, QF, HF No. */
}; };
...@@ -149,6 +149,7 @@ static tree pure_tree = NULL_TREE; ...@@ -149,6 +149,7 @@ static tree pure_tree = NULL_TREE;
static tree noreturn_tree = NULL_TREE; static tree noreturn_tree = NULL_TREE;
static tree interrupt_tree = NULL_TREE; static tree interrupt_tree = NULL_TREE;
/* Called to register all of our global variables with the garbage /* Called to register all of our global variables with the garbage
collector. */ collector. */
...@@ -236,6 +237,7 @@ c4x_override_options () ...@@ -236,6 +237,7 @@ c4x_override_options ()
/* This is called before c4x_override_options. */ /* This is called before c4x_override_options. */
void void
c4x_optimization_options (level, size) c4x_optimization_options (level, size)
int level; int level;
...@@ -252,6 +254,7 @@ c4x_optimization_options (level, size) ...@@ -252,6 +254,7 @@ c4x_optimization_options (level, size)
flag_branch_on_count_reg = 1; flag_branch_on_count_reg = 1;
} }
/* Write an ASCII string. */ /* Write an ASCII string. */
#define C4X_ASCII_LIMIT 40 #define C4X_ASCII_LIMIT 40
...@@ -329,20 +332,20 @@ c4x_hard_regno_mode_ok (regno, mode) ...@@ -329,20 +332,20 @@ c4x_hard_regno_mode_ok (regno, mode)
switch (mode) switch (mode)
{ {
#if Pmode != QImode #if Pmode != QImode
case Pmode: /* Pointer (24/32 bits) */ case Pmode: /* Pointer (24/32 bits). */
#endif #endif
case QImode: /* Integer (32 bits) */ case QImode: /* Integer (32 bits). */
return IS_INT_REGNO (regno); return IS_INT_REGNO (regno);
case QFmode: /* Float, Double (32 bits) */ case QFmode: /* Float, Double (32 bits). */
case HFmode: /* Long Double (40 bits) */ case HFmode: /* Long Double (40 bits). */
return IS_EXT_REGNO (regno); return IS_EXT_REGNO (regno);
case CCmode: /* Condition Codes */ case CCmode: /* Condition Codes. */
case CC_NOOVmode: /* Condition Codes */ case CC_NOOVmode: /* Condition Codes. */
return IS_ST_REGNO (regno); return IS_ST_REGNO (regno);
case HImode: /* Long Long (64 bits) */ case HImode: /* Long Long (64 bits). */
/* We need two registers to store long longs. Note that /* We need two registers to store long longs. Note that
it is much easier to constrain the first register it is much easier to constrain the first register
to start on an even boundary. */ to start on an even boundary. */
...@@ -351,7 +354,7 @@ c4x_hard_regno_mode_ok (regno, mode) ...@@ -351,7 +354,7 @@ c4x_hard_regno_mode_ok (regno, mode)
&& (regno & 1) == 0; && (regno & 1) == 0;
default: default:
return 0; /* We don't support these modes */ return 0; /* We don't support these modes. */
} }
return 0; return 0;
...@@ -401,9 +404,9 @@ static int c4x_fp_reglist[2] = {R2_REGNO, R3_REGNO}; ...@@ -401,9 +404,9 @@ static int c4x_fp_reglist[2] = {R2_REGNO, R3_REGNO};
void void
c4x_init_cumulative_args (cum, fntype, libname) c4x_init_cumulative_args (cum, fntype, libname)
CUMULATIVE_ARGS *cum; /* argument info to initialize */ CUMULATIVE_ARGS *cum; /* Argument info to initialize. */
tree fntype; /* tree ptr for function decl */ tree fntype; /* Tree ptr for function decl. */
rtx libname; /* SYMBOL_REF of library name or 0 */ rtx libname; /* SYMBOL_REF of library name or 0. */
{ {
tree param, next_param; tree param, next_param;
...@@ -480,10 +483,10 @@ c4x_init_cumulative_args (cum, fntype, libname) ...@@ -480,10 +483,10 @@ c4x_init_cumulative_args (cum, fntype, libname)
void void
c4x_function_arg_advance (cum, mode, type, named) c4x_function_arg_advance (cum, mode, type, named)
CUMULATIVE_ARGS *cum; /* current arg information */ CUMULATIVE_ARGS *cum; /* Current arg information. */
enum machine_mode mode; /* current arg mode */ enum machine_mode mode; /* Current arg mode. */
tree type; /* type of the argument or 0 if lib support */ tree type; /* Type of the arg or 0 if lib support. */
int named; /* whether or not the argument was named */ int named; /* Whether or not the argument was named. */
{ {
if (TARGET_DEBUG) if (TARGET_DEBUG)
fprintf (stderr, "c4x_function_adv(mode=%s, named=%d)\n\n", fprintf (stderr, "c4x_function_adv(mode=%s, named=%d)\n\n",
...@@ -527,16 +530,16 @@ c4x_function_arg_advance (cum, mode, type, named) ...@@ -527,16 +530,16 @@ c4x_function_arg_advance (cum, mode, type, named)
struct rtx_def * struct rtx_def *
c4x_function_arg (cum, mode, type, named) c4x_function_arg (cum, mode, type, named)
CUMULATIVE_ARGS *cum; /* current arg information */ CUMULATIVE_ARGS *cum; /* Current arg information. */
enum machine_mode mode; /* current arg mode */ enum machine_mode mode; /* Current arg mode. */
tree type; /* type of the argument or 0 if lib support */ tree type; /* Type of the arg or 0 if lib support. */
int named; /* != 0 for normal args, == 0 for ... args */ int named; /* != 0 for normal args, == 0 for ... args. */
{ {
int reg = 0; /* default to passing argument on stack */ int reg = 0; /* Default to passing argument on stack. */
if (! cum->init) if (! cum->init)
{ {
/* We can handle at most 2 floats in R2, R3 */ /* We can handle at most 2 floats in R2, R3. */
cum->maxfloats = (cum->floats > 2) ? 2 : cum->floats; cum->maxfloats = (cum->floats > 2) ? 2 : cum->floats;
/* We can handle at most 6 integers minus number of floats passed /* We can handle at most 6 integers minus number of floats passed
...@@ -615,7 +618,7 @@ c4x_va_start (stdarg_p, valist, nextarg) ...@@ -615,7 +618,7 @@ c4x_va_start (stdarg_p, valist, nextarg)
/* C[34]x arguments grow in weird ways (downwards) that the standard /* C[34]x arguments grow in weird ways (downwards) that the standard
varargs stuff can't handle. */ varargs stuff can't handle.. */
rtx rtx
c4x_va_arg (valist, type) c4x_va_arg (valist, type)
tree valist, type; tree valist, type;
...@@ -702,7 +705,7 @@ c4x_interrupt_function_p () ...@@ -702,7 +705,7 @@ c4x_interrupt_function_p ()
TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
return 1; return 1;
/* Look for TI style c_intnn */ /* Look for TI style c_intnn. */
return current_function_name[0] == 'c' return current_function_name[0] == 'c'
&& current_function_name[1] == '_' && current_function_name[1] == '_'
&& current_function_name[2] == 'i' && current_function_name[2] == 'i'
...@@ -757,7 +760,7 @@ c4x_function_prologue (file, size) ...@@ -757,7 +760,7 @@ c4x_function_prologue (file, size)
if (c4x_isr_reg_used_p (regno)) if (c4x_isr_reg_used_p (regno))
{ {
fprintf (file, "\tpush\t%s\n", reg_names[regno]); fprintf (file, "\tpush\t%s\n", reg_names[regno]);
if (IS_EXT_REGNO (regno)) /* save 32MSB of R0--R11 */ if (IS_EXT_REGNO (regno)) /* Save 32MSB of R0--R11. */
fprintf (file, "\tpushf\t%s\n", float_reg_names[regno]); fprintf (file, "\tpushf\t%s\n", float_reg_names[regno]);
} }
} }
...@@ -834,7 +837,7 @@ c4x_function_prologue (file, size) ...@@ -834,7 +837,7 @@ c4x_function_prologue (file, size)
{ {
if ((regno == R6_REGNO) || (regno == R7_REGNO)) if ((regno == R6_REGNO) || (regno == R7_REGNO))
{ {
/* R6 and R7 are saved as floating point */ /* R6 and R7 are saved as floating point. */
if (TARGET_PRESERVE_FLOAT) if (TARGET_PRESERVE_FLOAT)
fprintf (file, "\tpush\t%s\n", reg_names[regno]); fprintf (file, "\tpush\t%s\n", reg_names[regno]);
fprintf (file, "\tpushf\t%s\n", float_reg_names[regno]); fprintf (file, "\tpushf\t%s\n", float_reg_names[regno]);
...@@ -872,7 +875,7 @@ c4x_function_epilogue (file, size) ...@@ -872,7 +875,7 @@ c4x_function_epilogue (file, size)
/* For __assembler__ function build no epilogue. */ /* For __assembler__ function build no epilogue. */
if (c4x_assembler_function_p ()) if (c4x_assembler_function_p ())
{ {
fprintf (file, "\trets\n"); /* Play it safe */ fprintf (file, "\trets\n"); /* Play it safe. */
return; return;
} }
...@@ -929,7 +932,7 @@ c4x_function_epilogue (file, size) ...@@ -929,7 +932,7 @@ c4x_function_epilogue (file, size)
} }
else else
{ {
dont_pop_ar3 = 0; /* If we use ar3, we need to pop it */ dont_pop_ar3 = 0; /* If we use ar3, we need to pop it. */
if (size || current_function_args_size) if (size || current_function_args_size)
{ {
/* If we are ommitting the frame pointer, we still have /* If we are ommitting the frame pointer, we still have
...@@ -1306,9 +1309,9 @@ c4x_check_legit_addr (mode, addr, strict) ...@@ -1306,9 +1309,9 @@ c4x_check_legit_addr (mode, addr, strict)
rtx addr; rtx addr;
int strict; int strict;
{ {
rtx base = NULL_RTX; /* Base register (AR0-AR7) */ rtx base = NULL_RTX; /* Base register (AR0-AR7). */
rtx indx = NULL_RTX; /* Index register (IR0,IR1) */ rtx indx = NULL_RTX; /* Index register (IR0,IR1). */
rtx disp = NULL_RTX; /* Displacement */ rtx disp = NULL_RTX; /* Displacement. */
enum rtx_code code; enum rtx_code code;
code = GET_CODE (addr); code = GET_CODE (addr);
...@@ -1369,7 +1372,7 @@ c4x_check_legit_addr (mode, addr, strict) ...@@ -1369,7 +1372,7 @@ c4x_check_legit_addr (mode, addr, strict)
case REG: case REG:
if (REG_P (op1)) if (REG_P (op1))
{ {
base = op0; /* base + index */ base = op0; /* Base + index. */
indx = op1; indx = op1;
if (IS_INDEX_REG (base) || IS_ADDR_REG (indx)) if (IS_INDEX_REG (base) || IS_ADDR_REG (indx))
{ {
...@@ -1379,7 +1382,7 @@ c4x_check_legit_addr (mode, addr, strict) ...@@ -1379,7 +1382,7 @@ c4x_check_legit_addr (mode, addr, strict)
} }
else else
{ {
base = op0; /* base + displacement */ base = op0; /* Base + displacement. */
disp = op1; disp = op1;
} }
break; break;
...@@ -1723,16 +1726,16 @@ c4x_output_cbranch (form, seq) ...@@ -1723,16 +1726,16 @@ c4x_output_cbranch (form, seq)
void void
c4x_print_operand (file, op, letter) c4x_print_operand (file, op, letter)
FILE *file; /* file to write to */ FILE *file; /* File to write to. */
rtx op; /* operand to print */ rtx op; /* Operand to print. */
int letter; /* %<letter> or 0 */ int letter; /* %<letter> or 0. */
{ {
rtx op1; rtx op1;
enum rtx_code code; enum rtx_code code;
switch (letter) switch (letter)
{ {
case '#': /* delayed */ case '#': /* Delayed. */
if (final_sequence) if (final_sequence)
asm_fprintf (file, "d"); asm_fprintf (file, "d");
return; return;
...@@ -1741,32 +1744,32 @@ c4x_print_operand (file, op, letter) ...@@ -1741,32 +1744,32 @@ c4x_print_operand (file, op, letter)
code = GET_CODE (op); code = GET_CODE (op);
switch (letter) switch (letter)
{ {
case 'A': /* direct address */ case 'A': /* Direct address. */
if (code == CONST_INT || code == SYMBOL_REF) if (code == CONST_INT || code == SYMBOL_REF)
asm_fprintf (file, "@"); asm_fprintf (file, "@");
break; break;
case 'H': /* sethi */ case 'H': /* Sethi. */
output_addr_const (file, op); output_addr_const (file, op);
return; return;
case 'I': /* reversed condition */ case 'I': /* Reversed condition. */
code = reverse_condition (code); code = reverse_condition (code);
break; break;
case 'L': /* log 2 of constant */ case 'L': /* Log 2 of constant. */
if (code != CONST_INT) if (code != CONST_INT)
fatal_insn ("c4x_print_operand: %%L inconsistency", op); fatal_insn ("c4x_print_operand: %%L inconsistency", op);
fprintf (file, "%d", exact_log2 (INTVAL (op))); fprintf (file, "%d", exact_log2 (INTVAL (op)));
return; return;
case 'N': /* ones complement of small constant */ case 'N': /* Ones complement of small constant. */
if (code != CONST_INT) if (code != CONST_INT)
fatal_insn ("c4x_print_operand: %%N inconsistency", op); fatal_insn ("c4x_print_operand: %%N inconsistency", op);
fprintf (file, "%d", ~INTVAL (op)); fprintf (file, "%d", ~INTVAL (op));
return; return;
case 'K': /* generate ldp(k) if direct address */ case 'K': /* Generate ldp(k) if direct address. */
if (! TARGET_SMALL if (! TARGET_SMALL
&& code == MEM && code == MEM
&& GET_CODE (XEXP (op, 0)) == LO_SUM && GET_CODE (XEXP (op, 0)) == LO_SUM
...@@ -1783,8 +1786,8 @@ c4x_print_operand (file, op, letter) ...@@ -1783,8 +1786,8 @@ c4x_print_operand (file, op, letter)
} }
return; return;
case 'M': /* generate ldp(k) if direct address */ case 'M': /* Generate ldp(k) if direct address. */
if (! TARGET_SMALL /* only used in asm statements */ if (! TARGET_SMALL /* Only used in asm statements. */
&& code == MEM && code == MEM
&& (GET_CODE (XEXP (op, 0)) == CONST && (GET_CODE (XEXP (op, 0)) == CONST
|| GET_CODE (XEXP (op, 0)) == SYMBOL_REF)) || GET_CODE (XEXP (op, 0)) == SYMBOL_REF))
...@@ -1795,7 +1798,7 @@ c4x_print_operand (file, op, letter) ...@@ -1795,7 +1798,7 @@ c4x_print_operand (file, op, letter)
} }
return; return;
case 'O': /* offset address */ case 'O': /* Offset address. */
if (code == MEM && c4x_autoinc_operand (op, Pmode)) if (code == MEM && c4x_autoinc_operand (op, Pmode))
break; break;
else if (code == MEM) else if (code == MEM)
...@@ -1806,10 +1809,10 @@ c4x_print_operand (file, op, letter) ...@@ -1806,10 +1809,10 @@ c4x_print_operand (file, op, letter)
fatal_insn ("c4x_print_operand: %%O inconsistency", op); fatal_insn ("c4x_print_operand: %%O inconsistency", op);
return; return;
case 'C': /* call */ case 'C': /* Call. */
break; break;
case 'U': /* call/callu */ case 'U': /* Call/callu. */
if (code != SYMBOL_REF) if (code != SYMBOL_REF)
asm_fprintf (file, "u"); asm_fprintf (file, "u");
return; return;
...@@ -1988,26 +1991,26 @@ c4x_print_operand_address (file, addr) ...@@ -1988,26 +1991,26 @@ c4x_print_operand_address (file, addr)
{ {
fprintf (file, "*+%s(%s)", fprintf (file, "*+%s(%s)",
reg_names[REGNO (op1)], reg_names[REGNO (op1)],
reg_names[REGNO (op0)]); /* index + base */ reg_names[REGNO (op0)]); /* Index + base. */
} }
else else
{ {
fprintf (file, "*+%s(%s)", fprintf (file, "*+%s(%s)",
reg_names[REGNO (op0)], reg_names[REGNO (op0)],
reg_names[REGNO (op1)]); /* base + index */ reg_names[REGNO (op1)]); /* Base + index. */
} }
} }
else if (INTVAL (op1) < 0) else if (INTVAL (op1) < 0)
{ {
fprintf (file, "*-%s(%d)", fprintf (file, "*-%s(%d)",
reg_names[REGNO (op0)], reg_names[REGNO (op0)],
-INTVAL (op1)); /* base - displacement */ -INTVAL (op1)); /* Base - displacement. */
} }
else else
{ {
fprintf (file, "*+%s(%d)", fprintf (file, "*+%s(%d)",
reg_names[REGNO (op0)], reg_names[REGNO (op0)],
INTVAL (op1)); /* base + displacement */ INTVAL (op1)); /* Base + displacement. */
} }
} }
else else
...@@ -2043,8 +2046,10 @@ c4x_print_operand_address (file, addr) ...@@ -2043,8 +2046,10 @@ c4x_print_operand_address (file, addr)
} }
} }
/* Return nonzero if the floating point operand will fit /* Return nonzero if the floating point operand will fit
in the immediate field. */ in the immediate field. */
static int static int
c4x_immed_float_p (op) c4x_immed_float_p (op)
rtx op; rtx op;
...@@ -2062,16 +2067,17 @@ c4x_immed_float_p (op) ...@@ -2062,16 +2067,17 @@ c4x_immed_float_p (op)
convval[1] = 0; convval[1] = 0;
} }
/* sign extend exponent */ /* Sign extend exponent. */
exponent = (((convval[0] >> 24) & 0xff) ^ 0x80) - 0x80; exponent = (((convval[0] >> 24) & 0xff) ^ 0x80) - 0x80;
if (exponent == -128) if (exponent == -128)
return 1; /* 0.0 */ return 1; /* 0.0 */
if ((convval[0] & 0x00000fff) != 0 || convval[1] != 0) if ((convval[0] & 0x00000fff) != 0 || convval[1] != 0)
return 0; /* Precision doesn't fit */ return 0; /* Precision doesn't fit. */
return (exponent <= 7) /* Positive exp */ return (exponent <= 7) /* Positive exp. */
&& (exponent >= -7); /* Negative exp */ && (exponent >= -7); /* Negative exp. */
} }
/* The last instruction in a repeat block cannot be a Bcond, DBcound, /* The last instruction in a repeat block cannot be a Bcond, DBcound,
CALL, CALLCond, TRAPcond, RETIcond, RETScond, IDLE, RPTB or RPTS. CALL, CALLCond, TRAPcond, RETIcond, RETScond, IDLE, RPTB or RPTS.
...@@ -2144,6 +2150,7 @@ c4x_rptb_nop_p (insn) ...@@ -2144,6 +2150,7 @@ c4x_rptb_nop_p (insn)
Any additional labels can be emitted at this point. In addition, if Any additional labels can be emitted at this point. In addition, if
the desired loop count register was not allocated, this routine does the desired loop count register was not allocated, this routine does
nothing. */ nothing. */
void void
c4x_rptb_insert (insn) c4x_rptb_insert (insn)
rtx insn; rtx insn;
...@@ -2411,7 +2418,7 @@ c4x_Q_constraint (op) ...@@ -2411,7 +2418,7 @@ c4x_Q_constraint (op)
/* ARx + 5-bit unsigned const /* ARx + 5-bit unsigned const
*ARx, *+ARx(n) for n < 32 */ *ARx, *+ARx(n) for n < 32. */
int int
c4x_R_constraint (op) c4x_R_constraint (op)
...@@ -2526,7 +2533,7 @@ c4x_S_constraint (op) ...@@ -2526,7 +2533,7 @@ c4x_S_constraint (op)
op0 = XEXP (op1, 0); op0 = XEXP (op1, 0);
op1 = XEXP (op1, 1); op1 = XEXP (op1, 1);
return REG_P (op0) && REG_P (op1); return REG_P (op0) && REG_P (op1);
/* pre or post_modify with a displacement of 0 or 1 /* Pre or post_modify with a displacement of 0 or 1
should not be generated. */ should not be generated. */
} }
break; break;
...@@ -2599,7 +2606,7 @@ c4x_S_indirect (op) ...@@ -2599,7 +2606,7 @@ c4x_S_indirect (op)
op1 = XEXP (op1, 1); op1 = XEXP (op1, 1);
return REG_P (op0) && IS_ADDR_OR_PSEUDO_REG (op0) return REG_P (op0) && IS_ADDR_OR_PSEUDO_REG (op0)
&& REG_P (op1) && IS_INDEX_OR_PSEUDO_REG (op1); && REG_P (op1) && IS_INDEX_OR_PSEUDO_REG (op1);
/* pre or post_modify with a displacement of 0 or 1 /* Pre or post_modify with a displacement of 0 or 1
should not be generated. */ should not be generated. */
} }
...@@ -3066,7 +3073,9 @@ symbolic_address_operand (op, mode) ...@@ -3066,7 +3073,9 @@ symbolic_address_operand (op, mode)
} }
} }
/* Check dst operand of a move instruction. */ /* Check dst operand of a move instruction. */
int int
dst_operand (op, mode) dst_operand (op, mode)
rtx op; rtx op;
...@@ -3084,6 +3093,7 @@ dst_operand (op, mode) ...@@ -3084,6 +3093,7 @@ dst_operand (op, mode)
/* Check src operand of two operand arithmetic instructions. */ /* Check src operand of two operand arithmetic instructions. */
int int
src_operand (op, mode) src_operand (op, mode)
rtx op; rtx op;
...@@ -3315,7 +3325,7 @@ c4x_S_address_parse (op, base, incdec, index, disp) ...@@ -3315,7 +3325,7 @@ c4x_S_address_parse (op, base, incdec, index, disp)
return; return;
} }
} }
/* Fallthrough */ /* Fallthrough. */
default: default:
fatal_insn ("Invalid indirect (S) memory address", op); fatal_insn ("Invalid indirect (S) memory address", op);
...@@ -3444,23 +3454,23 @@ valid_parallel_load_store (operands, mode) ...@@ -3444,23 +3454,23 @@ valid_parallel_load_store (operands, mode)
|| (GET_CODE (op3) == MEM && reg_mentioned_p (op0, XEXP (op3, 0))))) || (GET_CODE (op3) == MEM && reg_mentioned_p (op0, XEXP (op3, 0)))))
return 0; return 0;
/* LDI||LDI */ /* LDI||LDI. */
if (GET_CODE (op0) == REG && GET_CODE (op2) == REG) if (GET_CODE (op0) == REG && GET_CODE (op2) == REG)
return (REGNO (op0) != REGNO (op2)) return (REGNO (op0) != REGNO (op2))
&& GET_CODE (op1) == MEM && GET_CODE (op3) == MEM && GET_CODE (op1) == MEM && GET_CODE (op3) == MEM
&& ! c4x_address_conflict (op1, op3, 0, 0); && ! c4x_address_conflict (op1, op3, 0, 0);
/* STI||STI */ /* STI||STI. */
if (GET_CODE (op1) == REG && GET_CODE (op3) == REG) if (GET_CODE (op1) == REG && GET_CODE (op3) == REG)
return GET_CODE (op0) == MEM && GET_CODE (op2) == MEM return GET_CODE (op0) == MEM && GET_CODE (op2) == MEM
&& ! c4x_address_conflict (op0, op2, 1, 1); && ! c4x_address_conflict (op0, op2, 1, 1);
/* LDI||STI */ /* LDI||STI. */
if (GET_CODE (op0) == REG && GET_CODE (op3) == REG) if (GET_CODE (op0) == REG && GET_CODE (op3) == REG)
return GET_CODE (op1) == MEM && GET_CODE (op2) == MEM return GET_CODE (op1) == MEM && GET_CODE (op2) == MEM
&& ! c4x_address_conflict (op1, op2, 0, 1); && ! c4x_address_conflict (op1, op2, 0, 1);
/* STI||LDI */ /* STI||LDI. */
if (GET_CODE (op1) == REG && GET_CODE (op2) == REG) if (GET_CODE (op1) == REG && GET_CODE (op2) == REG)
return GET_CODE (op0) == MEM && GET_CODE (op3) == MEM return GET_CODE (op0) == MEM && GET_CODE (op3) == MEM
&& ! c4x_address_conflict (op0, op3, 1, 0); && ! c4x_address_conflict (op0, op3, 1, 0);
...@@ -3726,7 +3736,7 @@ int valid_operands (code, operands, mode) ...@@ -3726,7 +3736,7 @@ int valid_operands (code, operands, mode)
valid one into an invalid one, when the second operand is also a valid one into an invalid one, when the second operand is also a
memory operand. The alternative is not to allow two memory memory operand. The alternative is not to allow two memory
operands for an insn when not optimizing. The problem only rarely operands for an insn when not optimizing. The problem only rarely
occurs, for example with the C-torture program DFcmp.c */ occurs, for example with the C-torture program DFcmp.c. */
return ! optimize || c4x_valid_operands (code, operands, mode, 0); return ! optimize || c4x_valid_operands (code, operands, mode, 0);
} }
...@@ -4126,7 +4136,8 @@ ir1_mem_operand (op, mode) ...@@ -4126,7 +4136,8 @@ ir1_mem_operand (op, mode)
} }
/* We allow autoincrement addressing. */ /* This is similar to operand_subword but allows autoincrement
addressing. */
rtx rtx
c4x_operand_subword (op, i, validate_address, mode) c4x_operand_subword (op, i, validate_address, mode)
...@@ -4298,25 +4309,25 @@ c4x_handle_pragma (p_getc, p_ungetc, pname) ...@@ -4298,25 +4309,25 @@ c4x_handle_pragma (p_getc, p_ungetc, pname)
data_tree = chainon (data_tree, new); data_tree = chainon (data_tree, new);
else if (strcmp (pname, "FUNC_CANNOT_INLINE") == 0) else if (strcmp (pname, "FUNC_CANNOT_INLINE") == 0)
; /* ignore */ ; /* Ignore. */
else if (strcmp (pname, "FUNC_EXT_CALLED") == 0) else if (strcmp (pname, "FUNC_EXT_CALLED") == 0)
; /* ignore */ ; /* Ignore. */
else if (strcmp (pname, "FUNC_IS_PURE") == 0) else if (strcmp (pname, "FUNC_IS_PURE") == 0)
pure_tree = chainon (pure_tree, new); pure_tree = chainon (pure_tree, new);
else if (strcmp (pname, "FUNC_IS_SYSTEM") == 0) else if (strcmp (pname, "FUNC_IS_SYSTEM") == 0)
; /* ignore */ ; /* Ignore. */
else if (strcmp (pname, "FUNC_NEVER_RETURNS") == 0) else if (strcmp (pname, "FUNC_NEVER_RETURNS") == 0)
noreturn_tree = chainon (noreturn_tree, new); noreturn_tree = chainon (noreturn_tree, new);
else if (strcmp (pname, "FUNC_NO_GLOBAL_ASG") == 0) else if (strcmp (pname, "FUNC_NO_GLOBAL_ASG") == 0)
; /* ignore */ ; /* Ignore. */
else if (strcmp (pname, "FUNC_NO_IND_ASG") == 0) else if (strcmp (pname, "FUNC_NO_IND_ASG") == 0)
; /* ignore */ ; /* Ignore. */
else if (strcmp (pname, "INTERRUPT") == 0) else if (strcmp (pname, "INTERRUPT") == 0)
interrupt_tree = chainon (interrupt_tree, new); interrupt_tree = chainon (interrupt_tree, new);
...@@ -4395,6 +4406,7 @@ c4x_valid_type_attribute_p (type, attributes, identifier, args) ...@@ -4395,6 +4406,7 @@ c4x_valid_type_attribute_p (type, attributes, identifier, args)
/* !!! FIXME to emit RPTS correctly. */ /* !!! FIXME to emit RPTS correctly. */
int int
c4x_rptb_rpts_p (insn, op) c4x_rptb_rpts_p (insn, op)
rtx insn, op; rtx insn, op;
...@@ -4443,10 +4455,12 @@ c4x_rptb_rpts_p (insn, op) ...@@ -4443,10 +4455,12 @@ c4x_rptb_rpts_p (insn, op)
A set of an address register followed by a use occurs a 2 cycle A set of an address register followed by a use occurs a 2 cycle
stall (reduced to a single cycle on the c40 using LDA), while stall (reduced to a single cycle on the c40 using LDA), while
a read of an address register followed by a use occurs a single cycle. */ a read of an address register followed by a use occurs a single cycle. */
#define SET_USE_COST 3 #define SET_USE_COST 3
#define SETLDA_USE_COST 2 #define SETLDA_USE_COST 2
#define READ_USE_COST 2 #define READ_USE_COST 2
int int
c4x_adjust_cost (insn, link, dep_insn, cost) c4x_adjust_cost (insn, link, dep_insn, cost)
rtx insn; rtx insn;
......
...@@ -21,15 +21,15 @@ ...@@ -21,15 +21,15 @@
the Free Software Foundation, 59 Temple Place - Suite 330, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
/* RUN-TIME TARGET SPECIFICATION */ /* RUN-TIME TARGET SPECIFICATION. */
#define C4x 1 #define C4x 1
/* Name of the c4x assembler */ /* Name of the c4x assembler. */
#define ASM_PROG "c4x-as" #define ASM_PROG "c4x-as"
/* Name of the c4x linker */ /* Name of the c4x linker. */
#define LD_PROG "c4x-ld" #define LD_PROG "c4x-ld"
...@@ -90,32 +90,32 @@ ...@@ -90,32 +90,32 @@
/* Target compilation option flags. */ /* Target compilation option flags. */
#define SMALL_MEMORY_FLAG 0x0000001 /* small memory model */ #define SMALL_MEMORY_FLAG 0x0000001 /* Small memory model. */
#define MPYI_FLAG 0x0000002 /* use 24-bit MPYI for C3x */ #define MPYI_FLAG 0x0000002 /* Use 24-bit MPYI for C3x. */
#define FAST_FIX_FLAG 0x0000004 /* fast fixing of floats */ #define FAST_FIX_FLAG 0x0000004 /* Fast fixing of floats. */
#define RPTS_FLAG 0x0000008 /* allow use of RPTS */ #define RPTS_FLAG 0x0000008 /* Allow use of RPTS. */
#define C3X_FLAG 0x0000010 /* emit C3x code */ #define C3X_FLAG 0x0000010 /* Emit C3x code. */
#define TI_FLAG 0x0000020 /* be compatible with TI assembler */ #define TI_FLAG 0x0000020 /* Be compatible with TI assembler. */
#define PARANOID_FLAG 0x0000040 /* be paranoid about DP reg. in ISRs */ #define PARANOID_FLAG 0x0000040 /* Be paranoid about DP reg. in ISRs. */
#define MEMPARM_FLAG 0x0000080 /* pass arguments on stack */ #define MEMPARM_FLAG 0x0000080 /* Pass arguments on stack. */
#define DEVEL_FLAG 0x0000100 /* enable features under development */ #define DEVEL_FLAG 0x0000100 /* Enable features under development. */
#define RPTB_FLAG 0x0000200 /* enable repeat block */ #define RPTB_FLAG 0x0000200 /* Enable repeat block. */
#define BK_FLAG 0x0000400 /* use BK as general register */ #define BK_FLAG 0x0000400 /* Use BK as general register. */
#define DB_FLAG 0x0000800 /* use decrement and branch for C3x */ #define DB_FLAG 0x0000800 /* Use decrement and branch for C3x. */
#define DEBUG_FLAG 0x0001000 /* enable debugging of GCC */ #define DEBUG_FLAG 0x0001000 /* Enable debugging of GCC. */
#define HOIST_FLAG 0x0002000 /* force constants into registers */ #define HOIST_FLAG 0x0002000 /* Force constants into registers. */
#define LOOP_UNSIGNED_FLAG 0x0004000 /* allow unsigned loop counters */ #define LOOP_UNSIGNED_FLAG 0x0004000 /* Allow unsigned loop counters. */
#define FORCE_FLAG 0x0008000 /* force op0 and op1 to be same */ #define FORCE_FLAG 0x0008000 /* Force op0 and op1 to be same. */
#define PRESERVE_FLOAT_FLAG 0x0010000 /* save all 40 bits for floats */ #define PRESERVE_FLOAT_FLAG 0x0010000 /* Save all 40 bits for floats. */
#define PARALLEL_PACK_FLAG 0x0020000 /* allow parallel insn packing */ #define PARALLEL_PACK_FLAG 0x0020000 /* Allow parallel insn packing. */
#define PARALLEL_MPY_FLAG 0x0040000 /* allow MPY||ADD, MPY||SUB insns */ #define PARALLEL_MPY_FLAG 0x0040000 /* Allow MPY||ADD, MPY||SUB insns. */
#define ALIASES_FLAG 0x0080000 /* assume mem refs possibly aliased */ #define ALIASES_FLAG 0x0080000 /* Assume mem refs possibly aliased. */
#define C30_FLAG 0x0100000 /* emit C30 code */ #define C30_FLAG 0x0100000 /* Emit C30 code. */
#define C31_FLAG 0x0200000 /* emit C31 code */ #define C31_FLAG 0x0200000 /* Emit C31 code. */
#define C32_FLAG 0x0400000 /* emit C32 code */ #define C32_FLAG 0x0400000 /* Emit C32 code. */
#define C40_FLAG 0x1000000 /* emit C40 code */ #define C40_FLAG 0x1000000 /* Emit C40 code. */
#define C44_FLAG 0x2000000 /* emit C44 code */ #define C44_FLAG 0x2000000 /* Emit C44 code. */
/* Run-time compilation parameters selecting different hardware subsets. /* Run-time compilation parameters selecting different hardware subsets.
...@@ -218,7 +218,7 @@ ...@@ -218,7 +218,7 @@
"Assume that pointers not aliased" }, \ "Assume that pointers not aliased" }, \
{ "", TARGET_DEFAULT, ""} } { "", TARGET_DEFAULT, ""} }
/* Default target switches */ /* Default target switches. */
/* Play safe, not the fastest code. */ /* Play safe, not the fastest code. */
#define TARGET_DEFAULT ALIASES_FLAG | PARALLEL_PACK_FLAG \ #define TARGET_DEFAULT ALIASES_FLAG | PARALLEL_PACK_FLAG \
...@@ -279,7 +279,7 @@ extern int target_flags; ...@@ -279,7 +279,7 @@ extern int target_flags;
#define BCT_CHECK_LOOP_ITERATIONS !(TARGET_LOOP_UNSIGNED) #define BCT_CHECK_LOOP_ITERATIONS !(TARGET_LOOP_UNSIGNED)
/* -mcpu=XX with XX = target DSP version number */ /* -mcpu=XX with XX = target DSP version number. */
/* This macro is similar to `TARGET_SWITCHES' but defines names of /* This macro is similar to `TARGET_SWITCHES' but defines names of
command options that have values. Its definition is an command options that have values. Its definition is an
...@@ -318,11 +318,11 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string; ...@@ -318,11 +318,11 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) c4x_optimization_options(LEVEL, SIZE) #define OPTIMIZATION_OPTIONS(LEVEL,SIZE) c4x_optimization_options(LEVEL, SIZE)
/* Run Time Target Specification */ /* Run Time Target Specification. */
#define TARGET_VERSION fprintf (stderr, " (TMS320C[34]x, TI syntax)"); #define TARGET_VERSION fprintf (stderr, " (TMS320C[34]x, TI syntax)");
/* Storage Layout */ /* Storage Layout. */
#define BITS_BIG_ENDIAN 0 #define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0 #define BYTES_BIG_ENDIAN 0
...@@ -350,7 +350,7 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string; ...@@ -350,7 +350,7 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
#define EMPTY_FIELD_BOUNDARY 32 #define EMPTY_FIELD_BOUNDARY 32
#define STRICT_ALIGNMENT 0 #define STRICT_ALIGNMENT 0
#define TARGET_FLOAT_FORMAT C4X_FLOAT_FORMAT #define TARGET_FLOAT_FORMAT C4X_FLOAT_FORMAT
#define MAX_FIXED_MODE_SIZE 64 /* HImode */ #define MAX_FIXED_MODE_SIZE 64 /* HImode. */
/* Number of bits in the high and low parts of a two stage /* Number of bits in the high and low parts of a two stage
load of an immediate constant. */ load of an immediate constant. */
...@@ -509,9 +509,9 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string; ...@@ -509,9 +509,9 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
#define FIXED_REGISTERS \ #define FIXED_REGISTERS \
{ \ { \
/* R0 R1 R2 R3 R4 R5 R6 R7 AR0 AR1 AR2 AR3 AR4 AR5 AR6 AR7 */ \ /* R0 R1 R2 R3 R4 R5 R6 R7 AR0 AR1 AR2 AR3 AR4 AR5 AR6 AR7. */ \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* DP IR0 IR1 BK SP ST DIE IIE IIF RS RE RC R8 R9 R10 R11 */ \ /* DP IR0 IR1 BK SP ST DIE IIE IIF RS RE RC R8 R9 R10 R11. */ \
1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 \ 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 \
} }
...@@ -528,9 +528,9 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string; ...@@ -528,9 +528,9 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
#define CALL_USED_REGISTERS \ #define CALL_USED_REGISTERS \
{ \ { \
/* R0 R1 R2 R3 R4 R5 R6 R7 AR0 AR1 AR2 AR3 AR4 AR5 AR6 AR7 */ \ /* R0 R1 R2 R3 R4 R5 R6 R7 AR0 AR1 AR2 AR3 AR4 AR5 AR6 AR7. */ \
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, \ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, \
/* DP IR0 IR1 BK SP ST DIE IIE IIF RS RE RC R8 R9 R10 R11 */ \ /* DP IR0 IR1 BK SP ST DIE IIE IIF RS RE RC R8 R9 R10 R11. */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 \
} }
...@@ -548,9 +548,9 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string; ...@@ -548,9 +548,9 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
{ \ { \
int i; \ int i; \
\ \
reg_names[DIE_REGNO] = "ie"; /* clobber die */ \ reg_names[DIE_REGNO] = "ie"; /* Clobber die. */ \
reg_names[IF_REGNO] = "if"; /* clobber iie */ \ reg_names[IF_REGNO] = "if"; /* Clobber iie. */ \
reg_names[IOF_REGNO] = "iof"; /* clobber iif */ \ reg_names[IOF_REGNO] = "iof"; /* Clobber iif. */ \
\ \
for (i = R8_REGNO; i <= R11_REGNO; i++) \ for (i = R8_REGNO; i <= R11_REGNO; i++) \
{ \ { \
...@@ -565,7 +565,7 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string; ...@@ -565,7 +565,7 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
} \ } \
} }
/* Order of Allocation of Registers */ /* Order of Allocation of Registers. */
/* List the order in which to allocate registers. Each register must be /* List the order in which to allocate registers. Each register must be
listed once, even those in FIXED_REGISTERS. listed once, even those in FIXED_REGISTERS.
...@@ -653,20 +653,20 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string; ...@@ -653,20 +653,20 @@ extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
enum reg_class enum reg_class
{ {
NO_REGS, NO_REGS,
R0R1_REGS, /* 't' */ R0R1_REGS, /* 't'. */
R2R3_REGS, /* 'u' */ R2R3_REGS, /* 'u'. */
EXT_LOW_REGS, /* 'q' */ EXT_LOW_REGS, /* 'q'. */
EXT_REGS, /* 'f' */ EXT_REGS, /* 'f'. */
ADDR_REGS, /* 'a' */ ADDR_REGS, /* 'a'. */
INDEX_REGS, /* 'x' */ INDEX_REGS, /* 'x'. */
BK_REG, /* 'k' */ BK_REG, /* 'k'. */
SP_REG, /* 'b' */ SP_REG, /* 'b'. */
RC_REG, /* 'v' */ RC_REG, /* 'v'. */
COUNTER_REGS, /* */ COUNTER_REGS, /* */
INT_REGS, /* 'c' */ INT_REGS, /* 'c'. */
GENERAL_REGS, /* 'r' */ GENERAL_REGS, /* 'r'. */
DP_REG, /* 'z' */ DP_REG, /* 'z'. */
ST_REG, /* 'y' */ ST_REG, /* 'y'. */
ALL_REGS, ALL_REGS,
LIM_REG_CLASSES LIM_REG_CLASSES
}; };
...@@ -701,22 +701,22 @@ enum reg_class ...@@ -701,22 +701,22 @@ enum reg_class
#define REG_CLASS_CONTENTS \ #define REG_CLASS_CONTENTS \
{ \ { \
{0x00000000}, /* No registers */ \ {0x00000000}, /* No registers. */ \
{0x00000003}, /* 't' R0-R1 */ \ {0x00000003}, /* 't' R0-R1 . */ \
{0x0000000c}, /* 'u' R2-R3 */ \ {0x0000000c}, /* 'u' R2-R3 . */ \
{0x000000ff}, /* 'q' R0-R7 */ \ {0x000000ff}, /* 'q' R0-R7 . */ \
{0xf00000ff}, /* 'f' R0-R11 */ \ {0xf00000ff}, /* 'f' R0-R11 */ \
{0x0000ff00}, /* 'a' AR0-AR7 */ \ {0x0000ff00}, /* 'a' AR0-AR7. */ \
{0x00060000}, /* 'x' IR0-IR1 */ \ {0x00060000}, /* 'x' IR0-IR1. */ \
{0x00080000}, /* 'k' BK */ \ {0x00080000}, /* 'k' BK. */ \
{0x00100000}, /* 'b' SP */ \ {0x00100000}, /* 'b' SP. */ \
{0x08000000}, /* 'v' RC */ \ {0x08000000}, /* 'v' RC. */ \
{0x0800ff00}, /* RC,AR0-AR7 */ \ {0x0800ff00}, /* RC,AR0-AR7. */ \
{0x0e1eff00}, /* 'c' AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC */ \ {0x0e1eff00}, /* 'c' AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC. */ \
{0xfe1effff}, /* 'r' R0-R11, AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC */\ {0xfe1effff}, /* 'r' R0-R11, AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC. */\
{0x00010000}, /* 'z' DP */ \ {0x00010000}, /* 'z' DP. */ \
{0x00200000}, /* 'y' ST */ \ {0x00200000}, /* 'y' ST. */ \
{0xffffffff}, /* All registers */ \ {0xffffffff}, /* All registers. */ \
} }
/* The same information, inverted: /* The same information, inverted:
...@@ -821,26 +821,27 @@ enum reg_class ...@@ -821,26 +821,27 @@ enum reg_class
(((MODE) == CCmode || (MODE) == CC_NOOVmode) ? 1 : ((MODE) == HFmode) ? 1 : \ (((MODE) == CCmode || (MODE) == CC_NOOVmode) ? 1 : ((MODE) == HFmode) ? 1 : \
((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) ((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
#define IS_INT5_CONST(VAL) (((VAL) <= 15) && ((VAL) >= -16)) /* 'K' */ #define IS_INT5_CONST(VAL) (((VAL) <= 15) && ((VAL) >= -16)) /* 'K'. */
#define IS_UINT5_CONST(VAL) (((VAL) <= 31) && ((VAL) >= 0)) /* 'R' */ #define IS_UINT5_CONST(VAL) (((VAL) <= 31) && ((VAL) >= 0)) /* 'R'. */
#define IS_INT8_CONST(VAL) (((VAL) <= 127) && ((VAL) >= -128)) /* 'J' */ #define IS_INT8_CONST(VAL) (((VAL) <= 127) && ((VAL) >= -128)) /* 'J'. */
#define IS_UINT8_CONST(VAL) (((VAL) <= 255) && ((VAL) >= 0)) /* 'M' */ #define IS_UINT8_CONST(VAL) (((VAL) <= 255) && ((VAL) >= 0)) /* 'M'. */
#define IS_INT16_CONST(VAL) (((VAL) <= 32767) && ((VAL) >= -32768)) /* 'I' */ #define IS_INT16_CONST(VAL) (((VAL) <= 32767) && ((VAL) >= -32768)) /* 'I'. */
#define IS_UINT16_CONST(VAL) (((VAL) <= 65535) && ((VAL) >= 0)) /* 'L' */ #define IS_UINT16_CONST(VAL) (((VAL) <= 65535) && ((VAL) >= 0)) /* 'L'. */
#define IS_NOT_UINT16_CONST(VAL) IS_UINT16_CONST(~(VAL)) /* 'N' */ #define IS_NOT_UINT16_CONST(VAL) IS_UINT16_CONST(~(VAL)) /* 'N'. */
#define IS_HIGH_CONST(VAL) (! TARGET_C3X && (((VAL) & 0xffff) == 0)) /* 'O' */ #define IS_HIGH_CONST(VAL) \
(! TARGET_C3X && (((VAL) & 0xffff) == 0)) /* 'O'. */
#define IS_DISP1_CONST(VAL) (((VAL) <= 1) && ((VAL) >= -1)) /* 'S' */ #define IS_DISP1_CONST(VAL) (((VAL) <= 1) && ((VAL) >= -1)) /* 'S'. */
#define IS_DISP8_CONST(VAL) (((VAL) <= 255) && ((VAL) >= -255)) /* 'Q' */ #define IS_DISP8_CONST(VAL) (((VAL) <= 255) && ((VAL) >= -255)) /* 'Q'. */
#define IS_DISP1_OFF_CONST(VAL) (IS_DISP1_CONST (VAL) \ #define IS_DISP1_OFF_CONST(VAL) (IS_DISP1_CONST (VAL) \
&& IS_DISP1_CONST (VAL + 1)) && IS_DISP1_CONST (VAL + 1))
...@@ -973,7 +974,7 @@ enum reg_class ...@@ -973,7 +974,7 @@ enum reg_class
#define C4X_ARG0 -2 #define C4X_ARG0 -2
#define C4X_LOC0 1 #define C4X_LOC0 1
/* Basic Stack Layout */ /* Basic Stack Layout. */
/* The stack grows upward, stack frame grows upward, and args grow /* The stack grows upward, stack frame grows upward, and args grow
downward. */ downward. */
...@@ -986,25 +987,25 @@ enum reg_class ...@@ -986,25 +987,25 @@ enum reg_class
/* Define this if pushing a word on the stack /* Define this if pushing a word on the stack
makes the stack pointer a smaller address. */ makes the stack pointer a smaller address. */
/* #define STACK_GROWS_DOWNWARD */ /* #define STACK_GROWS_DOWNWARD. */
/* Like the dsp16xx, i370, i960, and we32k ports */ /* Like the dsp16xx, i370, i960, and we32k ports. */
/* Define this if the nominal address of the stack frame /* Define this if the nominal address of the stack frame
is at the high-address end of the local variables; is at the high-address end of the local variables;
that is, each additional local variable allocated that is, each additional local variable allocated
goes at a more negative offset in the frame. */ goes at a more negative offset in the frame. */
/* #define FRAME_GROWS_DOWNWARD */ /* #define FRAME_GROWS_DOWNWARD. */
/* Registers That Address the Stack Frame */ /* Registers That Address the Stack Frame. */
#define STACK_POINTER_REGNUM SP_REGNO /* SP */ #define STACK_POINTER_REGNUM SP_REGNO /* SP. */
#define FRAME_POINTER_REGNUM AR3_REGNO /* AR3 */ #define FRAME_POINTER_REGNUM AR3_REGNO /* AR3. */
#define ARG_POINTER_REGNUM AR3_REGNO /* AR3 */ #define ARG_POINTER_REGNUM AR3_REGNO /* AR3. */
#define STATIC_CHAIN_REGNUM AR0_REGNO /* AR0 */ #define STATIC_CHAIN_REGNUM AR0_REGNO /* AR0. */
/* Eliminating Frame Pointer and Arg Pointer */ /* Eliminating Frame Pointer and Arg Pointer. */
#define FRAME_POINTER_REQUIRED 0 #define FRAME_POINTER_REQUIRED 0
...@@ -1020,7 +1021,7 @@ enum reg_class ...@@ -1020,7 +1021,7 @@ enum reg_class
(DEPTH) = -(offset + get_frame_size ()); \ (DEPTH) = -(offset + get_frame_size ()); \
} }
/* This is a hack... We need to specify a register. */ /* This is a hack... We need to specify a register. */
#define ELIMINABLE_REGS \ #define ELIMINABLE_REGS \
{{ FRAME_POINTER_REGNUM, FRAME_POINTER_REGNUM }} {{ FRAME_POINTER_REGNUM, FRAME_POINTER_REGNUM }}
...@@ -1041,14 +1042,14 @@ enum reg_class ...@@ -1041,14 +1042,14 @@ enum reg_class
} }
/* Passing Function Arguments on the Stack */ /* Passing Function Arguments on the Stack. */
#if 0 #if 0
#define PUSH_ROUNDING(BYTES) (BYTES) #define PUSH_ROUNDING(BYTES) (BYTES)
#endif #endif
#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
/* The following structure is used by calls.c, function.c, c4x.c */ /* The following structure is used by calls.c, function.c, c4x.c. */
typedef struct c4x_args typedef struct c4x_args
{ {
...@@ -1088,29 +1089,29 @@ CUMULATIVE_ARGS; ...@@ -1088,29 +1089,29 @@ CUMULATIVE_ARGS;
/* 1 if N is a possible register number for function argument passing. */ /* 1 if N is a possible register number for function argument passing. */
#define FUNCTION_ARG_REGNO_P(REGNO) \ #define FUNCTION_ARG_REGNO_P(REGNO) \
( ( ((REGNO) == AR2_REGNO) /* AR2 */ \ ( ( ((REGNO) == AR2_REGNO) /* AR2. */ \
|| ((REGNO) == R2_REGNO) /* R2 */ \ || ((REGNO) == R2_REGNO) /* R2. */ \
|| ((REGNO) == R3_REGNO) /* R3 */ \ || ((REGNO) == R3_REGNO) /* R3. */ \
|| ((REGNO) == RC_REGNO) /* RC */ \ || ((REGNO) == RC_REGNO) /* RC. */ \
|| ((REGNO) == RS_REGNO) /* RS */ \ || ((REGNO) == RS_REGNO) /* RS. */ \
|| ((REGNO) == RE_REGNO)) /* RE */ \ || ((REGNO) == RE_REGNO)) /* RE. */ \
? 1 \ ? 1 \
: 0) : 0)
/* How Scalar Function Values Are Returned */ /* How Scalar Function Values Are Returned. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \ #define FUNCTION_VALUE(VALTYPE, FUNC) \
gen_rtx(REG, TYPE_MODE(VALTYPE), R0_REGNO) /* Return in R0 */ gen_rtx(REG, TYPE_MODE(VALTYPE), R0_REGNO) /* Return in R0. */
#define LIBCALL_VALUE(MODE) \ #define LIBCALL_VALUE(MODE) \
gen_rtx(REG, MODE, R0_REGNO) /* Return in R0 */ gen_rtx(REG, MODE, R0_REGNO) /* Return in R0. */
#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == R0_REGNO) #define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == R0_REGNO)
/* How Large Values Are Returned */ /* How Large Values Are Returned. */
#define DEFAULT_PCC_STRUCT_RETURN 0 #define DEFAULT_PCC_STRUCT_RETURN 0
#define STRUCT_VALUE_REGNUM AR0_REGNO /* AR0 */ #define STRUCT_VALUE_REGNUM AR0_REGNO /* AR0. */
/* Varargs handling. */ /* Varargs handling. */
...@@ -1120,13 +1121,13 @@ CUMULATIVE_ARGS; ...@@ -1120,13 +1121,13 @@ CUMULATIVE_ARGS;
#define EXPAND_BUILTIN_VA_ARG(valist, type) \ #define EXPAND_BUILTIN_VA_ARG(valist, type) \
c4x_va_arg (valist, type) c4x_va_arg (valist, type)
/* Function Entry and Exit */ /* Function Entry and Exit. */
#define FUNCTION_PROLOGUE(FILE, SIZE) c4x_function_prologue(FILE, SIZE) #define FUNCTION_PROLOGUE(FILE, SIZE) c4x_function_prologue(FILE, SIZE)
#define FUNCTION_EPILOGUE(FILE, SIZE) c4x_function_epilogue(FILE, SIZE) #define FUNCTION_EPILOGUE(FILE, SIZE) c4x_function_epilogue(FILE, SIZE)
/* Generating Code for Profiling */ /* Generating Code for Profiling. */
/* Note that the generated assembly uses the ^ operator to load the 16 /* Note that the generated assembly uses the ^ operator to load the 16
MSBs of the address. This is not supported by the TI assembler. MSBs of the address. This is not supported by the TI assembler.
...@@ -1412,7 +1413,7 @@ CUMULATIVE_ARGS; ...@@ -1412,7 +1413,7 @@ CUMULATIVE_ARGS;
asm(" popf r0"); \ asm(" popf r0"); \
asm(" pop r0"); \ asm(" pop r0"); \
/* Implicit Calls to Library Routines */ /* Implicit Calls to Library Routines. */
#define MULQI3_LIBCALL "__mulqi3" #define MULQI3_LIBCALL "__mulqi3"
#define DIVQI3_LIBCALL "__divqi3" #define DIVQI3_LIBCALL "__divqi3"
...@@ -1571,7 +1572,7 @@ CUMULATIVE_ARGS; ...@@ -1571,7 +1572,7 @@ CUMULATIVE_ARGS;
|| GET_MODE (Y) == ABS) \ || GET_MODE (Y) == ABS) \
? CC_NOOVmode : CCmode) ? CC_NOOVmode : CCmode)
/* Addressing Modes */ /* Addressing Modes. */
#define HAVE_POST_INCREMENT 1 #define HAVE_POST_INCREMENT 1
#define HAVE_PRE_INCREMENT 1 #define HAVE_PRE_INCREMENT 1
...@@ -1722,7 +1723,7 @@ CUMULATIVE_ARGS; ...@@ -1722,7 +1723,7 @@ CUMULATIVE_ARGS;
#define ENCODE_SECTION_INFO(DECL) c4x_encode_section_info (DECL); #define ENCODE_SECTION_INFO(DECL) c4x_encode_section_info (DECL);
/* Descripting Relative Cost of Operations */ /* Descripting Relative Cost of Operations. */
/* Provide the costs of a rtl expression. This is in the body of a /* Provide the costs of a rtl expression. This is in the body of a
switch on CODE. switch on CODE.
...@@ -1843,7 +1844,7 @@ if (REG_P (OP1) && ! REG_P (OP0)) \ ...@@ -1843,7 +1844,7 @@ if (REG_P (OP1) && ! REG_P (OP0)) \
#define REGISTER_MOVE_COST(FROM, TO) 2 #define REGISTER_MOVE_COST(FROM, TO) 2
/* Memory move cost is same as fast register move. Maybe this should /* Memory move cost is same as fast register move. Maybe this should
be bumped up? */ be bumped up?. */
#define MEMORY_MOVE_COST(M,C,I) 4 #define MEMORY_MOVE_COST(M,C,I) 4
...@@ -2028,7 +2029,7 @@ dtors_section () \ ...@@ -2028,7 +2029,7 @@ dtors_section () \
} \ } \
else if (TREE_CODE (DECL) == VAR_DECL) \ else if (TREE_CODE (DECL) == VAR_DECL) \
{ \ { \
if ((0 && RELOC) /* should be (flag_pic && RELOC) */ \ if ((0 && RELOC) /* Should be (flag_pic && RELOC). */ \
|| ! TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ || ! TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \
|| ! DECL_INITIAL (DECL) \ || ! DECL_INITIAL (DECL) \
|| (DECL_INITIAL (DECL) != error_mark_node \ || (DECL_INITIAL (DECL) != error_mark_node \
...@@ -2050,7 +2051,7 @@ dtors_section () \ ...@@ -2050,7 +2051,7 @@ dtors_section () \
#define SELECT_RTX_SECTION(MODE, RTX) const_section() #define SELECT_RTX_SECTION(MODE, RTX) const_section()
/* Overall Framework of an Assembler File */ /* Overall Framework of an Assembler File. */
#define ASM_FILE_START(FILE) \ #define ASM_FILE_START(FILE) \
{ \ { \
...@@ -2148,9 +2149,9 @@ dtors_section () \ ...@@ -2148,9 +2149,9 @@ dtors_section () \
#define ASM_CLOSE_PAREN ")" #define ASM_CLOSE_PAREN ")"
/* Output and Generation of Labels */ /* Output and Generation of Labels. */
#define NO_DOT_IN_LABEL /* Only required for TI format */ #define NO_DOT_IN_LABEL /* Only required for TI format. */
#define ASM_OUTPUT_LABEL(FILE, NAME) \ #define ASM_OUTPUT_LABEL(FILE, NAME) \
do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0); do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0);
...@@ -2207,7 +2208,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM) ...@@ -2207,7 +2208,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM)
sprintf ((OUTPUT), "%s%d", (NAME), (LABELNO))) sprintf ((OUTPUT), "%s%d", (NAME), (LABELNO)))
/* Output of Dispatch Tables */ /* Output of Dispatch Tables. */
/* This is how to output an element of a case-vector that is absolute. */ /* This is how to output an element of a case-vector that is absolute. */
...@@ -2235,7 +2236,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM) ...@@ -2235,7 +2236,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM)
#define LONG_LONG_TYPE_SIZE 64 #define LONG_LONG_TYPE_SIZE 64
#define FLOAT_TYPE_SIZE 32 #define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 32 #define DOUBLE_TYPE_SIZE 32
#define LONG_DOUBLE_TYPE_SIZE 64 /* actually only 40 */ #define LONG_DOUBLE_TYPE_SIZE 64 /* Actually only 40. */
/* Allow #sccs in preprocessor. */ /* Allow #sccs in preprocessor. */
...@@ -2248,7 +2249,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM) ...@@ -2248,7 +2249,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM)
#define CPP_PREDEFINES "" #define CPP_PREDEFINES ""
/* Output of Uninitialized Variables */ /* Output of Uninitialized Variables. */
/* This says how to output an assembler line to define a local /* This says how to output an assembler line to define a local
uninitialized variable. */ uninitialized variable. */
...@@ -2270,12 +2271,12 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM) ...@@ -2270,12 +2271,12 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM)
assemble_name (FILE, (NAME)), \ assemble_name (FILE, (NAME)), \
fprintf (FILE, ",%u\n", (ROUNDED))) fprintf (FILE, ",%u\n", (ROUNDED)))
/* Macros Controlling Initialization Routines */ /* Macros Controlling Initialization Routines. */
#define OBJECT_FORMAT_COFF #define OBJECT_FORMAT_COFF
#define REAL_NM_FILE_NAME "c4x-nm" #define REAL_NM_FILE_NAME "c4x-nm"
/* Output of Assembler Instructions */ /* Output of Assembler Instructions. */
/* Register names when used for integer modes. */ /* Register names when used for integer modes. */
...@@ -2321,7 +2322,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM) ...@@ -2321,7 +2322,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM)
#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \ #define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \
(c4x_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS)) (c4x_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS))
/* Assembler Commands for Alignment */ /* Assembler Commands for Alignment. */
#define ASM_OUTPUT_SKIP(FILE, SIZE) \ #define ASM_OUTPUT_SKIP(FILE, SIZE) \
{ int c = SIZE; \ { int c = SIZE; \
...@@ -2339,7 +2340,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM) ...@@ -2339,7 +2340,7 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM)
/* Macros for SDB and DWARF Output (use .sdef instead of .def /* Macros for SDB and DWARF Output (use .sdef instead of .def
to avoid conflict with TI's use of .def) */ to avoid conflict with TI's use of .def). */
#define SDB_DELIM "\n" #define SDB_DELIM "\n"
#define SDB_DEBUGGING_INFO #define SDB_DEBUGGING_INFO
...@@ -2530,7 +2531,7 @@ do { fprintf (asm_out_file, "\t.sdef\t"); \ ...@@ -2530,7 +2531,7 @@ do { fprintf (asm_out_file, "\t.sdef\t"); \
/* MOVE_RATIO is the number of move instructions that is better than a /* MOVE_RATIO is the number of move instructions that is better than a
block move. */ block move. */
#define MOVE_RATIO 2 /* Default value */ #define MOVE_RATIO 2 /* Default value. */
#define BSS_SECTION_ASM_OP ".bss" #define BSS_SECTION_ASM_OP ".bss"
...@@ -2616,11 +2617,12 @@ if (final_sequence != NULL_RTX) \ ...@@ -2616,11 +2617,12 @@ if (final_sequence != NULL_RTX) \
/* Variables in c4x.c */ /* Variables in c4x.c */
extern enum reg_class c4x_regclass_map[];/* smallest class containing REGNO */ /* Smallest class containing REGNO. */
extern enum reg_class c4x_regclass_map[];
extern enum machine_mode c4x_caller_save_map[]; extern enum machine_mode c4x_caller_save_map[];
extern struct rtx_def *c4x_compare_op0; /* operand 0 for comparisons */ extern struct rtx_def *c4x_compare_op0; /* Operand 0 for comparisons. */
extern struct rtx_def *c4x_compare_op1; /* operand 1 for comparisons */ extern struct rtx_def *c4x_compare_op1; /* Operand 1 for comparisons. */
extern int c4x_rpts_cycles; /* max cycles for RPTS */ extern int c4x_rpts_cycles; /* Max cycles for RPTS. */
extern int c4x_cpu_version; /* cpu version C30/31/32/40/44 */ extern int c4x_cpu_version; /* Cpu version C30/31/32/40/44. */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment