Commit 2e16fb5a authored by Michael Beck's avatar Michael Beck
Browse files

more floating point immediate support

[r14775]
parent 82c1910c
......@@ -213,21 +213,16 @@ void arm_emit_mode(arm_emit_env_t *env, const ir_node *node) {
arm_emit_fpa_postfix(env->emit, mode);
}
/**
* Returns non-zero if a mode has a Immediate attribute.
*/
int is_immediate_node(const ir_node *irn) {
const arm_attr_t *attr = get_arm_attr_const(irn);
return ARM_GET_SHF_MOD(attr) == ARM_SHF_IMM;
}
/**
* Emit a const or SymConst value.
*/
void arm_emit_immediate(arm_emit_env_t *env, const ir_node *node) {
if (is_immediate_node(node)) {
const arm_attr_t *attr = get_arm_attr_const(node);
if (ARM_GET_SHF_MOD(attr) == ARM_SHF_IMM) {
be_emit_irprintf(env->emit, "#0x%X", arm_decode_imm_w_shift(get_arm_value(node)));
} else if (ARM_GET_FPA_IMM(attr)) {
be_emit_irprintf(env->emit, "#0x%F", get_arm_value(node));
} else if (is_arm_SymConst(node))
be_emit_ident(env->emit, get_arm_symconst_id(node));
else {
......
......@@ -47,7 +47,6 @@
#include "arm_nodes_attr.h"
#include "arm_new_nodes.h"
#include "gen_arm_regalloc_if_t.h"
#include "../beabi.h"
#include "bearch_arm_t.h"
......
......@@ -52,6 +52,12 @@ typedef enum _arm_shift_modifier {
/** set the shift modifier to flags */
#define ARM_SET_SHF_MOD(attr, mod) ((attr)->instr_fl = (((attr)->instr_fl & ~7) | (mod)))
/** fpa immediate bit */
#define ARM_FPA_IMM (1 << 3) /**< fpa floating point immediate */
#define ARM_GET_FPA_IMM(attr) ((attr)->instr_fl & ARM_FPA_IMM)
#define ARM_SET_FPA_IMM(attr) ((attr)->instr_fl |= ARM_FPA_IMM)
#define ARM_CLR_FPA_IMM(attr) ((attr)->instr_fl &= ~ARM_FPA_IMM)
/**
* Possible ARM condition codes.
......@@ -76,10 +82,10 @@ typedef enum _arm_condition {
} arm_condition;
/** Get the condition code from flags */
#define ARM_GET_COND(attr) (((attr)->instr_fl >> 3) & 15)
#define ARM_GET_COND(attr) (((attr)->instr_fl >> 4) & 15)
/** Set the condition code to flags */
#define ARM_SET_COND(attr, code) ((attr)->instr_fl = (((attr)->instr_fl & ~(15 << 3)) | ((code) << 3)))
#define ARM_SET_COND(attr, code) ((attr)->instr_fl = (((attr)->instr_fl & ~(15 << 4)) | ((code) << 4)))
/** Generic ARM node attributes. */
typedef struct _arm_attr_t {
......
......@@ -704,7 +704,7 @@ LoadStackM3 => {
# commutative operations
fpaAdd => {
fpaAdf => {
op_flags => "C",
irn_flags => "R",
comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b",
......@@ -712,15 +712,39 @@ fpaAdd => {
emit => '. adf%M %D0, %S0, %S1',
},
fpaMul => {
fpaAdf_i => {
op_flags => "C",
irn_flags => "R",
comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b",
attr => "tarval *tv",
init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;',
cmp_attr => 'return attr_a->value != attr_b->value;',
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
emit => '. adf%M %D0, %S0, %C',
},
fpaMuf => {
op_flags => "C",
irn_flags => "R",
comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b",
reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
emit =>'. muf%M %D0, %S0, %S1',
},
fpaFMul => {
fpaMuf_i => {
op_flags => "C",
irn_flags => "R",
comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b",
attr => "tarval *tv",
init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;',
cmp_attr => 'return attr_a->value != attr_b->value;',
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
emit => '. muf%M %D0, %S0, %C',
},
fpaFml => {
op_flags => "C",
irn_flags => "R",
comment => "construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b",
reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
emit =>'. fml%M %D0, %S0, %S1',
......@@ -744,21 +768,41 @@ fpaMin => {
# not commutative operations
fpaSub => {
fpaSuf => {
irn_flags => "R",
comment => "construct FPA Sub: Sub(a, b) = a - b",
reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
emit => '. suf%M %D0, %S0, %S1'
},
fpaRsb => {
fpaSuf_i => {
irn_flags => "R",
comment => "construct FPA Sub: Sub(a, b) = a - b",
attr => "tarval *tv",
init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;',
cmp_attr => 'return attr_a->value != attr_b->value;',
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
emit => '. suf%M %D0, %S0, %C'
},
fpaRsf => {
irn_flags => "R",
comment => "construct FPA reverse Sub: Sub(a, b) = b - a",
reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
emit => '. rsf%M %D0, %S0, %S1'
},
fpaDiv => {
fpaRsf_i => {
irn_flags => "R",
comment => "construct FPA reverse Sub: Sub(a, b) = b - a",
attr => "tarval *tv",
init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;',
cmp_attr => 'return attr_a->value != attr_b->value;',
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
emit => '. rsf%M %D0, %S0, %C'
},
fpaDvf => {
comment => "construct FPA Div: Div(a, b) = a / b",
attr => "ir_mode *op_mode",
init_attr => "attr->op_mode = op_mode;",
......@@ -767,7 +811,17 @@ fpaDiv => {
outs => [ "res", "M" ],
},
fpaRdv => {
fpaDvf_i => {
comment => "construct FPA Div: Div(a, b) = a / b",
attr => "ir_mode *op_mode, tarval *tv",
init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;',
cmp_attr => 'return attr_a->value != attr_b->value;',
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
emit =>'. dvf%M %D0, %S0, %C',
outs => [ "res", "M" ],
},
fpaRdf => {
comment => "construct FPA reverse Div: Div(a, b) = b / a",
attr => "ir_mode *op_mode",
init_attr => "attr->op_mode = op_mode;",
......@@ -776,7 +830,17 @@ fpaRdv => {
outs => [ "res", "M" ],
},
fpaFDiv => {
fpaRdf_i => {
comment => "construct FPA reverse Div: Div(a, b) = b / a",
attr => "ir_mode *op_mode, tarval *tv",
init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;',
cmp_attr => 'return attr_a->value != attr_b->value;',
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
emit =>'. rdf%M %D0, %S0, %S1',
outs => [ "res", "M" ],
},
fpaFdv => {
comment => "construct FPA Fast Div: Div(a, b) = a / b",
attr => "ir_mode *op_mode",
init_attr => "attr->op_mode = op_mode;",
......@@ -785,7 +849,17 @@ fpaFDiv => {
outs => [ "res", "M" ],
},
fpaFRdv => {
fpaFdv_i => {
comment => "construct FPA Fast Div: Div(a, b) = a / b",
attr => "ir_mode *op_mode, tarval *tv",
init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;',
cmp_attr => 'return attr_a->value != attr_b->value;',
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
emit =>'. fdv%M %D0, %S0, %C',
outs => [ "res", "M" ],
},
fpaFrd => {
comment => "construct FPA Fast reverse Div: Div(a, b) = b / a",
attr => "ir_mode *op_mode",
init_attr => "attr->op_mode = op_mode;",
......@@ -794,20 +868,52 @@ fpaFRdv => {
outs => [ "res", "M" ],
},
fpaMov => {
fpaFrd_i => {
comment => "construct FPA Fast reverse Div: Div(a, b) = b / a",
attr => "ir_mode *op_mode, tarval *tv",
init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;',
cmp_attr => 'return attr_a->value != attr_b->value;',
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
emit =>'. frd%M %D0, %S0, %C',
outs => [ "res", "M" ],
},
fpaMvf => {
irn_flags => "R",
comment => "construct FPA Move: b = a",
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
emit => '. mvf%M %S0, %D0',
},
fpaMnv => {
fpaMvf_i => {
irn_flags => "R",
comment => "represents a float constant",
attr => "tarval *tv",
init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;',
reg_req => { "out" => [ "fpa" ] },
mode => "get_tarval_mode(tv)",
emit => '. mvf %D0, %C',
cmp_attr => 'return attr_a->value != attr_b->value;'
},
fpaMnf => {
irn_flags => "R",
comment => "construct FPA Move Negated: b = -a",
reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
emit => '. mnf%M %S0, %D0',
},
fpaMnf_i => {
irn_flags => "R",
comment => "represents a float constant",
attr => "tarval *tv",
init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;',
reg_req => { "out" => [ "fpa" ] },
mode => "get_tarval_mode(tv)",
emit => '. mnf %D0, %C',
cmp_attr => 'return attr_a->value != attr_b->value;'
},
fpaAbs => {
irn_flags => "R",
comment => "construct FPA Absolute value: fAbsd(a) = |a|",
......@@ -939,7 +1045,7 @@ fpaConst => {
op_flags => "c",
irn_flags => "R",
comment => "construct a floating point constant",
attr => "tarval *tv, int is_imm",
attr => "tarval *tv",
init_attr => "attr->value = tv;",
mode => "get_tarval_mode(tv)",
reg_req => { "out" => [ "fpa" ] },
......
......@@ -279,7 +279,7 @@ static ir_node *gen_Conv(ir_node *node) {
if (mode_is_float(src_mode)) {
if (mode_is_float(dst_mode)) {
/* from float to float */
return new_rd_arm_fpaMov(dbg, irg, block, new_op, dst_mode);
return new_rd_arm_fpaMvf(dbg, irg, block, new_op, dst_mode);
}
else {
/* from float to int */
......@@ -377,9 +377,13 @@ static ir_node *gen_Add(ir_node *node) {
if (mode_is_float(mode)) {
env_cg->have_fp_insn = 1;
if (USE_FPA(env_cg->isa))
return new_rd_arm_fpaAdd(dbg, irg, block, new_op1, new_op2, mode);
else if (USE_VFP(env_cg->isa)) {
if (USE_FPA(env_cg->isa)) {
if (is_arm_fpaMvf_i(new_op1))
return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
if (is_arm_fpaMvf_i(new_op2))
return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
return new_rd_arm_fpaAdf(dbg, irg, block, new_op1, new_op2, mode);
} else if (USE_VFP(env_cg->isa)) {
assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet\n");
return NULL;
......@@ -448,8 +452,13 @@ static ir_node *gen_Mul(ir_node *node) {
if (mode_is_float(mode)) {
env_cg->have_fp_insn = 1;
if (USE_FPA(env_cg->isa))
return new_rd_arm_fpaMul(dbg, irg, block, new_op1, new_op2, mode);
if (USE_FPA(env_cg->isa)) {
if (is_arm_Mov_i(new_op1))
return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
if (is_arm_Mov_i(new_op2))
return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
return new_rd_arm_fpaMuf(dbg, irg, block, new_op1, new_op2, mode);
}
else if (USE_VFP(env_cg->isa)) {
assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet\n");
......@@ -483,9 +492,13 @@ static ir_node *gen_Quot(ir_node *node) {
assert(mode != mode_E && "IEEE Extended FP not supported");
env_cg->have_fp_insn = 1;
if (USE_FPA(env_cg->isa))
return new_rd_arm_fpaDiv(dbg, current_ir_graph, block, new_op1, new_op2, mode);
else if (USE_VFP(env_cg->isa)) {
if (USE_FPA(env_cg->isa)) {
if (is_arm_Mov_i(new_op1))
return new_rd_arm_fpaRdf_i(dbg, current_ir_graph, block, new_op2, mode, get_arm_value(new_op1));
if (is_arm_Mov_i(new_op2))
return new_rd_arm_fpaDvf_i(dbg, current_ir_graph, block, new_op1, mode, get_arm_value(new_op2));
return new_rd_arm_fpaDvf(dbg, current_ir_graph, block, new_op1, new_op2, mode);
} else if (USE_VFP(env_cg->isa)) {
assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet\n");
}
......@@ -573,9 +586,13 @@ static ir_node *gen_Sub(ir_node *node) {
if (mode_is_float(mode)) {
env_cg->have_fp_insn = 1;
if (USE_FPA(env_cg->isa))
return new_rd_arm_fpaSub(dbg, irg, block, new_op1, new_op2, mode);
else if (USE_VFP(env_cg->isa)) {
if (USE_FPA(env_cg->isa)) {
if (is_arm_Mov_i(new_op1))
return new_rd_arm_fpaRsf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
if (is_arm_Mov_i(new_op2))
return new_rd_arm_fpaSuf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
return new_rd_arm_fpaSuf(dbg, irg, block, new_op1, new_op2, mode);
} else if (USE_VFP(env_cg->isa)) {
assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet\n");
return NULL;
......@@ -738,7 +755,7 @@ static ir_node *gen_Minus(ir_node *node) {
if (mode_is_float(mode)) {
env_cg->have_fp_insn = 1;
if (USE_FPA(env_cg->isa))
return new_rd_arm_fpaMnv(dbg, current_ir_graph, block, op, mode);
return new_rd_arm_fpaMvf(dbg, current_ir_graph, block, op, mode);
else if (USE_VFP(env_cg->isa)) {
assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet\n");
......@@ -969,10 +986,48 @@ static ident *get_sc_ident(ir_node *symc) {
return NULL;
}
enum fpa_immediates {
fpa_null = 0,
fpa_one,
fpa_two,
fpa_three,
fpa_four,
fpa_five,
fpa_ten,
fpa_half,
fpa_max
};
static tarval *fpa_imm[3][fpa_max];
/**
* Check, if a floating point tarval is an fpa immediate, i.e.
* one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
*/
static int is_fpa_immediate(tarval *tv) {
ir_mode *mode = get_tarval_mode(tv);
int i, j, res = 1;
switch (get_mode_size_bits(mode)) {
case 32:
i = 0;
break;
case 64:
i = 1;
break;
default:
i = 2;
}
if (tarval_cmp(tv, get_tarval_null(mode)) & pn_Cmp_Lt) {
tv = tarval_neg(tv);
res = -1;
}
for (j = 0; j < fpa_max; ++j) {
if (tv == fpa_imm[i][j])
return res;
}
return 0;
}
......@@ -991,7 +1046,16 @@ static ir_node *gen_Const(ir_node *node) {
env_cg->have_fp_insn = 1;
if (USE_FPA(env_cg->isa)) {
tarval *tv = get_Const_tarval(node);
node = new_rd_arm_fpaConst(dbg, irg, block, tv, is_fpa_immediate(tv));
int imm = is_fpa_immediate(tv);
if (imm) {
if (imm > 0)
node = new_rd_arm_fpaMvf_i(dbg, irg, block, tv);
else
node = new_rd_arm_fpaMnf_i(dbg, irg, block, tv);
} else {
node = new_rd_arm_fpaConst(dbg, irg, block, tv);
}
/* ensure the const is schedules AFTER the barrier */
add_irn_dep(node, be_abi_get_start_barrier(env_cg->birg->abi));
return node;
......@@ -1318,25 +1382,25 @@ static ir_node *gen_Proj_Quot(ir_node *node) {
switch (proj) {
case pn_Quot_M:
if (is_arm_fpaDiv(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaDiv_M);
} else if (is_arm_fpaRdv(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaRdv_M);
} else if (is_arm_fpaFDiv(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFDiv_M);
} else if (is_arm_fpaFRdv(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFRdv_M);
if (is_arm_fpaDvf(new_pred) || is_arm_fpaDvf_i(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaDvf_M);
} else if (is_arm_fpaRdf(new_pred) || is_arm_fpaRdf_i(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaRdf_M);
} else if (is_arm_fpaFdv(new_pred) || is_arm_fpaFdv_i(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFdv_M);
} else if (is_arm_fpaFrd(new_pred) || is_arm_fpaFrd_i(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFrd_M);
}
break;
case pn_Quot_res:
if (is_arm_fpaDiv(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaDiv_res);
} else if (is_arm_fpaFDiv(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaRdv_res);
} else if (is_arm_fpaFDiv(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFDiv_res);
} else if (is_arm_fpaFDiv(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFRdv_res);
if (is_arm_fpaDvf(new_pred) || is_arm_fpaDvf_i(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaDvf_res);
} else if (is_arm_fpaRdf(new_pred) || is_arm_fpaRdf_i(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaRdf_res);
} else if (is_arm_fpaFdv(new_pred) || is_arm_fpaFdv_i(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFdv_res);
} else if (is_arm_fpaFrd(new_pred) || is_arm_fpaFrd_i(new_pred)) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFrd_res);
}
break;
default:
......@@ -1681,10 +1745,49 @@ static void arm_pretransform_node(void *arch_cg) {
cg->unknown_fpa = be_pre_transform_node(cg->unknown_fpa);
}
/**
* Initialize fpa Immediate support.
*/
static void arm_init_fpa_immediate(void) {
/* 0, 1, 2, 3, 4, 5, 10, or 0.5. */
fpa_imm[0][fpa_null] = get_tarval_null(mode_F);
fpa_imm[0][fpa_one] = get_tarval_one(mode_F);
fpa_imm[0][fpa_two] = new_tarval_from_str("2", 1, mode_F);
fpa_imm[0][fpa_three] = new_tarval_from_str("3", 1, mode_F);
fpa_imm[0][fpa_four] = new_tarval_from_str("4", 1, mode_F);
fpa_imm[0][fpa_five] = new_tarval_from_str("5", 1, mode_F);
fpa_imm[0][fpa_ten] = new_tarval_from_str("10", 2, mode_F);
fpa_imm[0][fpa_half] = new_tarval_from_str("0.5", 3, mode_F);
fpa_imm[1][fpa_null] = get_tarval_null(mode_D);
fpa_imm[1][fpa_one] = get_tarval_one(mode_D);
fpa_imm[1][fpa_two] = new_tarval_from_str("2", 1, mode_D);
fpa_imm[1][fpa_three] = new_tarval_from_str("3", 1, mode_D);
fpa_imm[1][fpa_four] = new_tarval_from_str("4", 1, mode_D);
fpa_imm[1][fpa_five] = new_tarval_from_str("5", 1, mode_D);
fpa_imm[1][fpa_ten] = new_tarval_from_str("10", 2, mode_D);
fpa_imm[1][fpa_half] = new_tarval_from_str("0.5", 3, mode_D);
fpa_imm[2][fpa_null] = get_tarval_null(mode_E);
fpa_imm[2][fpa_one] = get_tarval_one(mode_E);
fpa_imm[2][fpa_two] = new_tarval_from_str("2", 1, mode_E);
fpa_imm[2][fpa_three] = new_tarval_from_str("3", 1, mode_E);
fpa_imm[2][fpa_four] = new_tarval_from_str("4", 1, mode_E);
fpa_imm[2][fpa_five] = new_tarval_from_str("5", 1, mode_E);
fpa_imm[2][fpa_ten] = new_tarval_from_str("10", 2, mode_E);
fpa_imm[2][fpa_half] = new_tarval_from_str("0.5", 3, mode_E);
}
/**
* Transform a Firm graph into an ARM graph.
*/
void arm_transform_graph(arm_code_gen_t *cg) {
static int imm_initialized = 0;
if (! imm_initialized) {
arm_init_fpa_immediate();
imm_initialized = 1;
}
arm_register_transformers();
env_cg = cg;
be_transform_graph(cg->birg, arm_pretransform_node, cg);
......@@ -1692,6 +1795,4 @@ void arm_transform_graph(arm_code_gen_t *cg) {
void arm_init_transform(void) {
// FIRM_DBG_REGISTER(dbg, "firm.be.arm.transform");
/* 0, 1, 2, 3, 4, 5, 10, or 0.5. */
}
......@@ -1165,7 +1165,7 @@ static const backend_params *arm_get_libfirm_params(void) {
static arch_dep_params_t ad = {
1, /* allow subs */
1, /* Muls are fast enough on ARM but ... */
1, /* ... one shift would be possible better */
31, /* ... one shift would be possible better */
0, /* SMUL is needed, only in Arch M*/
0, /* UMUL is needed, only in Arch M */
32, /* SMUL & UMUL available for 32 bit */
......
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