aboutsummaryrefslogtreecommitdiff
path: root/lang/gpc/files/patch-am
diff options
context:
space:
mode:
Diffstat (limited to 'lang/gpc/files/patch-am')
-rw-r--r--lang/gpc/files/patch-am233
1 files changed, 233 insertions, 0 deletions
diff --git a/lang/gpc/files/patch-am b/lang/gpc/files/patch-am
new file mode 100644
index 000000000000..b6553c3474d1
--- /dev/null
+++ b/lang/gpc/files/patch-am
@@ -0,0 +1,233 @@
+*** stor-layout.c.orig Sat Nov 8 16:12:07 1997
+--- stor-layout.c Thu Mar 23 15:48:05 2000
+***************
+*** 65,70 ****
+--- 65,79 ----
+
+ int immediate_size_expand;
+
++ #ifdef GPC
++
++ /* Nonzero means that the size of a type may vary
++ within one function context. */
++
++ int size_volatile = 0;
++
++ #endif /* GPC */
++
+ tree
+ get_pending_sizes ()
+ {
+***************
+*** 102,109 ****
+ || global_bindings_p () < 0 || contains_placeholder_p (size))
+ return size;
+
+! size = save_expr (size);
+!
+ if (global_bindings_p ())
+ {
+ if (TREE_CONSTANT (size))
+--- 111,123 ----
+ || global_bindings_p () < 0 || contains_placeholder_p (size))
+ return size;
+
+! #ifdef GPC
+! if (! size_volatile)
+! size = save_expr (size);
+! #else /* not GPC */
+! size = save_expr (size);
+! #endif /* not GPC */
+!
+ if (global_bindings_p ())
+ {
+ if (TREE_CONSTANT (size))
+***************
+*** 119,125 ****
+--- 133,143 ----
+ Also, we would like to pass const0_rtx here, but don't have it. */
+ expand_expr (size, expand_expr (integer_zero_node, NULL_PTR, VOIDmode, 0),
+ VOIDmode, 0);
++ #ifdef GPC
++ else if (! size_volatile)
++ #else /* not GPC */
+ else
++ #endif /* not GPC */
+ pending_sizes = tree_cons (NULL_TREE, size, pending_sizes);
+
+ return size;
+***************
+*** 953,958 ****
+--- 971,1117 ----
+ }
+ break;
+
++ #ifdef GPC
++ /* Unfortunately the code for SET_TYPE in standard gcc 2.6.3 will
++ not work for pascal sets. The problem is that the code aligns
++ the set so that it always starts from the first bit of the
++ aligned set. (i.e it shifts bit 0 to the firt bit of the
++ aligned first word of the set). This is ok, if the set low
++ bound is zero (as in powersets) or any multiple of
++ "set_alignment". But this is not always the case in Pascal.
++
++ It causes problems when using set types with set constructors
++ in an expression, possibly the expression having ranges whose
++ both bounds are variable.
++
++ The method used in GPC is to adjust the sets so that the bits
++ are never shifted to the beginning of the aligned entity (in
++ gpc, it is a word), but rather more room is allocated in
++ front and behind of the actual set, so that both bounds are aligned
++ and then the size used by the set is counted.
++
++ The code below works as the original code for the special
++ cases when set low bound is 0 or a multiple of alignement,
++ but it also works for GPC.
++
++ Also, the code in the case when the bounds are variable
++ should work, and the algorithm is the same as in the
++ constant case, but the calculation is done in tree nodes
++ (so it can be folded wherever possible).
++
++ In this case, the original code called abort(). */
++
++ #ifndef SET_WORD_SIZE
++ #define SET_WORD_SIZE BITS_PER_WORD
++ #endif
++
++ case SET_TYPE:
++ if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST
++ && TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST)
++ {
++ int alignment = set_alignment ? set_alignment : SET_WORD_SIZE;
++ int aligned_size_in_bits;
++ int low_bound, high_bound;
++
++ int l_index = TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type)));
++ int h_index = TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
++
++ if (l_index == 0 && h_index == -1)
++ {
++ /* Special empty set node */
++ TYPE_SIZE (type) = size_zero_node;
++ TYPE_MODE (type) = VOIDmode;
++ TYPE_ALIGN (type) = 1;
++ break;
++ }
++
++ /* Calculate an aligned low bound from the set low bound */
++ low_bound = l_index - (l_index % alignment);
++
++ /* Calculate an aligned high bound from the set high bound */
++ high_bound = (alignment-1) + (alignment * (h_index / alignment));
++
++ /* This is the aligned size (both low and high aligned) */
++ aligned_size_in_bits = high_bound - low_bound + 1;
++
++ if (aligned_size_in_bits > alignment)
++ TYPE_MODE (type) = BLKmode;
++ else
++ TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1);
++
++ TYPE_SIZE (type) = size_int (aligned_size_in_bits);
++ TYPE_ALIGN (type) = alignment;
++ TYPE_PRECISION (type) = h_index - l_index + 1;
++ }
++ else
++ {
++ tree domain = TYPE_DOMAIN (type);
++ int alignment = set_alignment ? set_alignment : SET_WORD_SIZE;
++ tree align = build_int_2 (alignment, 0);
++
++ /* @@@@@ Negative bounds do not work here.
++
++ @@@ Although this should work, variable bound sets are
++ not supported in setop.c. */
++
++ extern tree build_binary_op (enum tree_code, tree, tree, int);
++
++ /* low_bound = low_index - (low_index % align); */
++ tree low_bound =
++ build_binary_op (MINUS_EXPR,
++ convert (integer_type_node,
++ TYPE_MIN_VALUE (domain)),
++ build_binary_op (TRUNC_MOD_EXPR,
++ convert (integer_type_node,
++ TYPE_MIN_VALUE (domain)),
++ align,
++ 0),
++ 0);
++
++ /* Upper bit number. Avoid overflow. */
++ /* upper_bound = (align-1) + (align * (high_index / align)); */
++ tree high_bound =
++ build_binary_op
++ (PLUS_EXPR,
++ build_int_2 (alignment - 1, 0),
++ build_binary_op (MULT_EXPR,
++ align,
++ build_binary_op (TRUNC_DIV_EXPR,
++ convert (integer_type_node,
++ TYPE_MAX_VALUE (domain)),
++ align,
++ 0),
++ 0),
++ 0);
++
++ /* Allocated TYPE_SIZE in bits, including possible aligning */
++ /* set_size_in_bits = high_bound - low_bound + 1; */
++ TYPE_SIZE (type) =
++ build_binary_op (PLUS_EXPR,
++ integer_one_node,
++ build_binary_op (MINUS_EXPR,
++ high_bound,
++ low_bound,
++ 0),
++ 0);
++
++ TYPE_ALIGN (type) = alignment;
++
++ /* Find out if the set fits in word_mode. If not, use BLKmode.
++ @@@ But it requires knowing the size, which is variable
++ in this case ... */
++
++ if (TYPE_SIZE (type)
++ && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
++ && TREE_INT_CST_LOW (TYPE_SIZE (type)) <= alignment)
++ TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1);
++ else
++ TYPE_MODE (type) = BLKmode;
++ }
++ break;
++ #else /* not GPC */
++
++
+ case SET_TYPE: /* Used by Chill and Pascal. */
+ if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST
+ || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST)
+***************
+*** 977,982 ****
+--- 1136,1142 ----
+ TYPE_PRECISION (type) = size_in_bits;
+ }
+ break;
++ #endif /* not GPC */
+
+ case FILE_TYPE:
+ /* The size may vary in different languages, so the language front end
+***************
+*** 1152,1157 ****
+--- 1312,1323 ----
+ >> (HOST_BITS_PER_WIDE_INT
+ - (precision - HOST_BITS_PER_WIDE_INT)))
+ : 0);
++ #ifdef GPC
++ /* Not only for Pascal, but other languages don't seem to care
++ about this. */
++ TREE_UNSIGNED (TYPE_MIN_VALUE (type)) = 1;
++ TREE_UNSIGNED (TYPE_MAX_VALUE (type)) = 1;
++ #endif /* GPC */
+ TREE_TYPE (TYPE_MIN_VALUE (type)) = type;
+ TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
+