Commit 3d4b192a by DJ Delorie Committed by DJ Delorie

stormy16.c (s16builtins, [...]): New.

* config/stormy16/stormy16.c (s16builtins,
xstormy16_init_builtins, xstormy16_expand_builtin): New.
* config/stormy16/stormy16.md (divmodhi4, sdivlh, udivlh): New.

From-SVN: r59312
parent 9a0a7d5d
2002-11-20 DJ Delorie <dj@redhat.com>
* config/stormy16/stormy16.c (s16builtins,
xstormy16_init_builtins, xstormy16_expand_builtin): New.
* config/stormy16/stormy16.md (divmodhi4, sdivlh, udivlh): New.
2002-11-20 Hans-Peter Nilsson <hp@bitrange.com>
* Makefile.in (RUN_GEN, VALGRIND_DRIVER_DEFINES): New variables.
......
......@@ -53,6 +53,9 @@ static void xstormy16_encode_section_info PARAMS ((tree, int));
static void xstormy16_asm_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
static void xstormy16_init_builtins PARAMS ((void));
static rtx xstormy16_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. */
struct rtx_def * xstormy16_compare_op0;
......@@ -2028,6 +2031,126 @@ xstormy16_handle_interrupt_attribute (node, name, args, flags, no_add_attrs)
return NULL_TREE;
}
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS xstormy16_init_builtins
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN xstormy16_expand_builtin
static struct {
const char *name;
int md_code;
const char *arg_ops; /* 0..9, t for temp register, r for return value */
const char *arg_types; /* s=short,l=long, upper case for unsigned */
} s16builtins[] = {
{ "__sdivlh", CODE_FOR_sdivlh, "rt01", "sls" },
{ "__smodlh", CODE_FOR_sdivlh, "tr01", "sls" },
{ "__udivlh", CODE_FOR_udivlh, "rt01", "SLS" },
{ "__umodlh", CODE_FOR_udivlh, "tr01", "SLS" },
{ 0, 0, 0, 0 }
};
static void
xstormy16_init_builtins ()
{
tree args, ret_type, arg;
int i, a;
ret_type = void_type_node;
for (i=0; s16builtins[i].name; i++)
{
args = void_list_node;
for (a=strlen (s16builtins[i].arg_types)-1; a>=0; a--)
{
switch (s16builtins[i].arg_types[a])
{
case 's': arg = short_integer_type_node; break;
case 'S': arg = short_unsigned_type_node; break;
case 'l': arg = long_integer_type_node; break;
case 'L': arg = long_unsigned_type_node; break;
default: abort();
}
if (a == 0)
ret_type = arg;
else
args = tree_cons (NULL_TREE, arg, args);
}
builtin_function (s16builtins[i].name,
build_function_type (ret_type, args),
i, BUILT_IN_MD, NULL, NULL);
}
}
static rtx
xstormy16_expand_builtin(exp, target, subtarget, mode, ignore)
tree exp;
rtx target;
rtx subtarget ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
int ignore ATTRIBUTE_UNUSED;
{
rtx op[10], args[10], pat, copyto[10], retval = 0;
tree fndecl, argtree;
int i, a, o, code;
fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
argtree = TREE_OPERAND (exp, 1);
i = DECL_FUNCTION_CODE (fndecl);
code = s16builtins[i].md_code;
for (a = 0; a < 10 && argtree; a++)
{
args[a] = expand_expr (TREE_VALUE (argtree), NULL_RTX, VOIDmode, 0);
argtree = TREE_CHAIN (argtree);
}
for (o = 0; s16builtins[i].arg_ops[o]; o++)
{
char ao = s16builtins[i].arg_ops[o];
char c = insn_data[code].operand[o].constraint[0];
int omode;
copyto[o] = 0;
omode = insn_data[code].operand[o].mode;
if (ao == 'r')
op[o] = target ? target : gen_reg_rtx (omode);
else if (ao == 't')
op[o] = gen_reg_rtx (omode);
else
op[o] = args[(int) hex_value (ao)];
if (! (*insn_data[code].operand[o].predicate) (op[o], GET_MODE (op[o])))
{
if (c == '+' || c == '=')
{
copyto[o] = op[o];
op[o] = gen_reg_rtx (omode);
}
else
op[o] = copy_to_mode_reg (omode, op[o]);
}
if (ao == 'r')
retval = op[o];
}
pat = GEN_FCN (code) (op[0], op[1], op[2], op[3], op[4],
op[5], op[6], op[7], op[8], op[9]);
emit_insn (pat);
for (o = 0; s16builtins[i].arg_ops[o]; o++)
if (copyto[o])
{
emit_move_insn (copyto[o], op[o]);
if (op[o] == retval)
retval = copyto[o];
}
return retval;
}
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
#undef TARGET_ASM_ALIGNED_SI_OP
......
......@@ -435,6 +435,42 @@
"div"
[(set_attr "psw_operand" "nop")])
;; Signed division giving both quotient and remainder
(define_insn "divmodhi4"
[(set (match_operand:HI 0 "register_operand" "=a")
(div:HI (match_operand:HI 1 "register_operand" "a")
(match_operand:HI 2 "register_operand" "c")))
(set (match_operand:HI 3 "register_operand" "=b")
(mod:HI (match_dup 1)
(match_dup 2)))]
""
"sdiv"
[(set_attr "psw_operand" "nop")])
;; Signed 32/16 division
(define_insn "sdivlh"
[(set (match_operand:HI 0 "register_operand" "=a")
(div:HI (match_operand:SI 2 "register_operand" "t")
(match_operand:HI 3 "register_operand" "c")))
(set (match_operand:HI 1 "register_operand" "=b")
(mod:HI (match_dup 2)
(match_dup 3)))]
""
"sdivlh"
[(set_attr "psw_operand" "nop")])
;; Unsigned 32/16 division
(define_insn "udivlh"
[(set (match_operand:HI 0 "register_operand" "=a")
(udiv:HI (match_operand:SI 2 "register_operand" "t")
(match_operand:HI 3 "register_operand" "c")))
(set (match_operand:HI 1 "register_operand" "=b")
(umod:HI (match_dup 2)
(match_dup 3)))]
""
"divlh"
[(set_attr "psw_operand" "nop")])
;; Negation
(define_expand "neghi2"
......
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