aboutsummaryrefslogtreecommitdiffstats
path: root/ortho/gcc
diff options
context:
space:
mode:
authorgingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7>2006-03-22 03:16:11 +0000
committergingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7>2006-03-22 03:16:11 +0000
commit6b6c24061f574e4dd5ece78ed78632c28da0b090 (patch)
treece5ea8514fdb369e86f4a2691906238a0ea984c9 /ortho/gcc
parentad38ef3d8cca89c15ec2ec45fc840d672333be4e (diff)
downloadghdl-6b6c24061f574e4dd5ece78ed78632c28da0b090.tar.gz
ghdl-6b6c24061f574e4dd5ece78ed78632c28da0b090.tar.bz2
ghdl-6b6c24061f574e4dd5ece78ed78632c28da0b090.zip
Fix x86_64 gcc issue.
Diffstat (limited to 'ortho/gcc')
-rw-r--r--ortho/gcc/ortho-lang.c119
1 files changed, 83 insertions, 36 deletions
diff --git a/ortho/gcc/ortho-lang.c b/ortho/gcc/ortho-lang.c
index f65b592e7..b8cdfe605 100644
--- a/ortho/gcc/ortho-lang.c
+++ b/ortho/gcc/ortho-lang.c
@@ -20,6 +20,8 @@
#include "cgraph.h"
#include "target.h"
#include "convert.h"
+#include "tree-pass.h"
+#include "tree-dump.h"
const int tree_identifier_size = sizeof (struct tree_identifier);
@@ -433,6 +435,7 @@ ortho_mark_addressable (tree exp)
case COMPONENT_REF:
case ARRAY_REF:
+ case ARRAY_RANGE_REF:
n = TREE_OPERAND (n, 0);
break;
@@ -1379,6 +1382,7 @@ new_slice (tree arr, tree res_type, tree index)
abort ();
ortho_mark_addressable (arr);
+ return build4 (ARRAY_RANGE_REF, res_type, arr, index, NULL_TREE, NULL_TREE);
el_type = TREE_TYPE (TREE_TYPE (arr));
el_ptr_type = build_pointer_type (el_type);
@@ -1452,78 +1456,117 @@ new_sizeof (tree atype, tree rtype)
return fold (build1 (NOP_EXPR, rtype, size));
}
-#if 0
-static tree
-ortho_build_addr (tree operand, tree atype)
-{
- tree base = exp;
-
- while (handled_component_p (base))
- base = TREE_OPERAND (base, 0);
-
- if (DECL_P (base))
- TREE_ADDRESSABLE (base) = 1;
+/* Convert the array expression EXP to a pointer. */
+static tree array_to_pointer_conversion (tree exp);
- return build1 (ADDR_EXPR, atype, exp);
-}
-#endif
-
-tree
-new_unchecked_address (tree lvalue, tree atype)
+static tree
+ortho_build_addr (tree lvalue, tree atype)
{
tree res;
if (TREE_CODE (lvalue) == INDIRECT_REF)
{
+ /* ADDR_REF(INDIRECT_REF(x)) -> x. */
res = TREE_OPERAND (lvalue, 0);
}
else
{
- ortho_mark_addressable (lvalue);
-
- if (TREE_TYPE (lvalue) != TREE_TYPE (atype))
+ /* &base[off] -> base+off. */
+ if (TREE_CODE (lvalue) == ARRAY_REF
+ || TREE_CODE (lvalue) == ARRAY_RANGE_REF)
{
- tree ptr;
- ptr = build_pointer_type (TREE_TYPE (lvalue));
- res = build1 (ADDR_EXPR, ptr, lvalue);
+ tree base = TREE_OPERAND (lvalue, 0);
+ tree idx = TREE_OPERAND (lvalue, 1);
+ tree offset;
+ tree base_type;
+
+ ortho_mark_addressable (base);
+
+ offset = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx,
+ array_ref_element_size (lvalue));
+
+ base = array_to_pointer_conversion (base);
+ base_type = TREE_TYPE (base);
+
+ res = build2 (PLUS_EXPR, base_type,
+ base, convert (base_type, offset));
}
else
- res = build1 (ADDR_EXPR, atype, lvalue);
+ {
+ ortho_mark_addressable (lvalue);
+
+ if (TREE_TYPE (lvalue) != TREE_TYPE (atype))
+ {
+ tree ptr;
+ ptr = build_pointer_type (TREE_TYPE (lvalue));
+ res = build1 (ADDR_EXPR, ptr, lvalue);
+ }
+ else
+ res = build1 (ADDR_EXPR, atype, lvalue);
+ }
+ res = fold (res);
}
if (TREE_TYPE (res) != atype)
- res = fold (build1 (NOP_EXPR, atype, res));
+ res = fold_build1 (NOP_EXPR, atype, res);
return res;
+}
-#if 0
- /* res = build_addr (lvalue, atype); */
- if (TREE_TYPE (res) != atype)
+/* Convert the array expression EXP to a pointer. */
+static tree
+array_to_pointer_conversion (tree exp)
+{
+ tree type = TREE_TYPE (exp);
+ tree adr;
+ tree restype = TREE_TYPE (type);
+ tree ptrtype;
+
+ gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+
+ /* Create a pointer to elements. */
+ ptrtype = build_pointer_type (restype);
+
+ switch (TREE_CODE (exp))
{
- if (TREE_CODE (TREE_TYPE (res)) != POINTER_TYPE)
- abort ();
- res = build1 (NOP_EXPR, atype, res);
+ case INDIRECT_REF:
+ return convert (ptrtype, TREE_OPERAND (exp, 0));
+
+ case VAR_DECL:
+ /* Convert array to pointer to elements. */
+ adr = build1 (ADDR_EXPR, ptrtype, exp);
+ ortho_mark_addressable (exp);
+ TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */
+ return adr;
+
+ default:
+ /* Get address. */
+ return ortho_build_addr (exp, ptrtype);
}
- return res;
-#endif
+}
+
+tree
+new_unchecked_address (tree lvalue, tree atype)
+{
+ return ortho_build_addr (lvalue, atype);
}
tree
new_address (tree lvalue, tree atype)
{
- return new_unchecked_address (lvalue, atype);
+ return ortho_build_addr (lvalue, atype);
}
tree
new_global_address (tree lvalue, tree atype)
{
- return new_unchecked_address (lvalue, atype);
+ return ortho_build_addr (lvalue, atype);
}
tree
new_global_unchecked_address (tree lvalue, tree atype)
{
- return new_unchecked_address (lvalue, atype);
+ return ortho_build_addr (lvalue, atype);
}
/* Return a pointer to function FUNC. */
@@ -1829,6 +1872,10 @@ finish_subprogram_body (void)
gimplify_function_tree (func);
+ /* Dump the genericized tree IR.
+ Enabled by -fdump-tree-gimple. */
+ dump_function (TDI_generic, func);
+
parent = DECL_CONTEXT (func);
if (parent != NULL)