Commit 2bcc27da authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Handle that some ldr*/str* only have 8 bit offests.

This fixes opt/fehler070.c on ARM.
parent 67131839
......@@ -129,7 +129,7 @@ static void peephole_arm_Str_Ldr(ir_node *node)
{
arm_load_store_attr_t *attr = get_arm_load_store_attr(node);
const int offset = attr->offset;
if (arm_is_offset12(offset))
if (arm_is_valid_offset(offset, attr->load_store_mode, is_arm_Str(node)))
return;
/* we should only have too big offsets for frame entities */
......@@ -176,3 +176,29 @@ void arm_peephole_optimization(ir_graph *irg)
be_peephole_opt(irg);
}
static inline bool arm_is_offset8(int32_t const v)
{
/* Symmetrical, because ARM uses sign+magnitude for offset. */
return -255 <= v && v <= 255;
}
static inline bool arm_is_offset12(int32_t const v)
{
/* Symmetrical, because ARM uses sign+magnitude for offset. */
return -4095 <= v && v <= 4095;
}
bool arm_is_valid_offset(int32_t const v, ir_mode *const mode, bool const is_store)
{
switch (get_mode_size_bits(mode)) {
case 8:
if (is_store || !mode_is_signed(mode)) {
case 32:
return arm_is_offset12(v);
} else {
default:
return arm_is_offset8(v);
}
}
}
......@@ -31,10 +31,6 @@ typedef struct arm_vals {
*/
void arm_gen_vals_from_word(uint32_t value, arm_vals *result);
static inline bool arm_is_offset12(int32_t const v)
{
/* Symmetrical, because ARM uses sign+magnitude for offset. */
return -4095 <= v && v <= 4095;
}
bool arm_is_valid_offset(int32_t v, ir_mode *mode, bool is_store);
#endif
......@@ -1097,14 +1097,14 @@ typedef struct arm_am_t {
long offset;
} arm_am_t;
static arm_am_t transform_am(ir_node *addr)
static arm_am_t transform_am(ir_node *addr, ir_mode *const mode, bool const is_store)
{
long offset = 0;
if (is_Add(addr)) {
ir_node *const r = get_Add_right(addr);
if (is_Const(r)) {
long const c = get_Const_long(r);
if (arm_is_offset12(offset)) {
if (arm_is_valid_offset(c, mode, is_store)) {
offset = c;
addr = get_Add_left(addr);
}
......@@ -1123,10 +1123,10 @@ static ir_node *gen_Load(ir_node *node)
{
ir_node *block = be_transform_nodes_block(node);
ir_node *ptr = get_Load_ptr(node);
arm_am_t am = transform_am(ptr);
ir_mode *mode = get_Load_mode(node);
arm_am_t am = transform_am(ptr, mode, false);
ir_node *mem = get_Load_mem(node);
ir_node *new_mem = be_transform_node(mem);
ir_mode *mode = get_Load_mode(node);
dbg_info *dbgi = get_irn_dbg_info(node);
if (get_Load_unaligned(node) == align_non_aligned)
panic("unaligned Loads not supported yet");
......@@ -1150,12 +1150,12 @@ static ir_node *gen_Store(ir_node *node)
{
ir_node *block = be_transform_nodes_block(node);
ir_node *ptr = get_Store_ptr(node);
arm_am_t am = transform_am(ptr);
ir_node *val = get_Store_value(node);
ir_mode *mode = get_irn_mode(val);
arm_am_t am = transform_am(ptr, mode, true);
ir_node *mem = get_Store_mem(node);
ir_node *new_mem = be_transform_node(mem);
ir_node *val = get_Store_value(node);
ir_node *new_val = be_transform_node(val);
ir_mode *mode = get_irn_mode(val);
dbg_info *dbgi = get_irn_dbg_info(node);
if (get_Store_unaligned(node) == align_non_aligned)
panic("unaligned Stores not supported yet");
......
Supports Markdown
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