return 2 * cost;
}
-/* BRANCH_COST
- Changing from the default of 1 doesn't affect code generation, presumably
- because there are no conditional move insns - when a condition is involved,
- the only option is to use a cbranch. */
-
/* For X, which must be a MEM RTX, return TRUE if it is an indirect memory
reference, @Rn or @Rn+. */
static bool
return false;
}
}
+
+#undef TARGET_INSN_COST
+#define TARGET_INSN_COST msp430_insn_cost
+
+static int
+msp430_insn_cost (rtx_insn *insn, bool speed ATTRIBUTE_UNUSED)
+{
+ if (recog_memoized (insn) < 0)
+ return 0;
+
+ /* The returned cost must be relative to COSTS_N_INSNS (1). An insn with a
+ length of 2 bytes is the smallest possible size and so must be equivalent
+ to COSTS_N_INSNS (1). */
+ return COSTS_N_INSNS (get_attr_length (insn) / 2);
+
+ /* FIXME Add more detailed costs when optimizing for speed.
+ For now the length of the instruction is a good approximiation and roughly
+ correlates with cycle cost. */
+}
+
\f
/* Function Entry and Exit */
#define HAS_LONG_COND_BRANCH 0
#define HAS_LONG_UNCOND_BRANCH 0
+/* The cost of a branch sequence is roughly 3 "cheap" instructions. */
+#define BRANCH_COST(speed_p, predictable_p) 3
+
+/* Override the default BRANCH_COST heuristic to indicate that it is preferable
+ to retain short-circuit operations, this results in significantly better
+ codesize and performance. */
+#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
+
#define LOAD_EXTEND_OP(M) ZERO_EXTEND
#define WORD_REGISTER_OPERATIONS 1
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+ (msp430x) and hwmult (none), when compiling at -O3. */
+
+char arr[2];
+char a;
+char *ptr;
+
+/*
+** foo:
+** ...
+** MOV.B \&a, \&arr\+1
+** MOV.* #arr\+2, \&ptr
+** ...
+*/
+
+void
+foo (void)
+{
+ arr[1] = a;
+ ptr = arr + 2;
+}
+
+extern void ext (void);
+
+/*
+** bar:
+** ...
+** CALL.* #ext
+** CALL.* #ext
+** ...
+*/
+
+void
+bar (void)
+{
+ ext ();
+ ext ();
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O3 -mhwmult=f5series" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+ (msp430x) and f5series hwmult, when compiling at -O3. */
+
+volatile unsigned long a;
+volatile unsigned int b;
+volatile unsigned long c;
+unsigned long res1;
+unsigned long res2;
+unsigned long res3;
+
+/*
+** foo:
+** ...
+** MOV.B #16, R14
+** CALL.* #__mspabi_slll
+** ...
+** MOV.* \&res2.*
+** ...
+** RLA.*RLC.*
+** ...
+** MOV.* \&res3.*
+** ...
+** RLA.*RLC.*
+** ...
+*/
+void foo (void)
+{
+ /* Use the shift library function for this. */
+ res1 = (a << 16) | b;
+ /* Emit 7 inline shifts for this. */
+ res2 *= 128;
+ /* Perform this multiplication inline, using addition and shifts. */
+ res3 *= 100;
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+ (msp430x) and hwmult (none), when compiling at -Os. */
+
+char arr[2];
+char a;
+char *ptr;
+
+/*
+** foo:
+** ...
+** MOV.B \&a, \&arr\+1
+** MOV.* #arr\+2, \&ptr
+** ...
+*/
+
+void
+foo (void)
+{
+ arr[1] = a;
+ ptr = arr + 2;
+}
+
+extern void ext (void);
+
+/*
+** bar:
+** ...
+** MOV.* #ext, R10
+** CALL.* R10
+** CALL.* R10
+** ...
+*/
+
+void
+bar (void)
+{
+ ext ();
+ ext ();
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-Os -mhwmult=f5series" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+ (msp430x) and f5series hwmult, when compiling at -Os. */
+
+volatile unsigned long a;
+volatile unsigned int b;
+volatile unsigned long c;
+unsigned long res1;
+unsigned long res2;
+unsigned long res3;
+
+/*
+** foo:
+** ...
+** MOV.B #16, R14
+** CALL.* #__mspabi_slll
+** ...
+** MOV.B #7, R14
+** CALL.* #__mspabi_slll
+** ...
+** MOV.B #100, R14
+** MOV.B #0, R15
+** ...
+** CALL.* #__mulsi2_f5
+** ...
+*/
+void foo (void)
+{
+ /* Use the shift library function for this. */
+ res1 = (a << 16) | b;
+ /* Likewise. */
+ res2 *= 128;
+ /* Use the hardware multiply library function for this. */
+ res3 *= 100;
+}