fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM); \
}
-/* Generate case label. */
-/* hack alert -- I don't get it ... what if its a really big case label?
- * wouldn't we have to say label_emitted also ?? */
+/* Generate case label. For HLASM we can change to the data CSECT
+ and put the vectors out of the code body. The assembler just
+ concatenates CSECTs with the same name. */
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
- fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM)
+ fprintf (FILE, "\tDS\t0F\n"); \
+ fprintf (FILE,"\tCSECT\n"); \
+ fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM)
+
+/* Put the CSECT back to the code body */
+
+#define ASM_OUTPUT_CASE_END(FILE, NUM, TABLE) \
+ assemble_name (FILE, mvs_function_name); \
+ fputs ("\tCSECT\n", FILE);
/* This is how to output an element of a case-vector that is absolute. */
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- mvs_check_page (FILE, 4, 0); \
fprintf (FILE, "\tDC\tA(L%d)\n", VALUE)
/* This is how to output an element of a case-vector that is relative. */
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- mvs_check_page (FILE, 4, 0); \
fprintf (FILE, "\tDC\tA(L%d-L%d)\n", VALUE, REL)
/* This is how to output an insn to push a register on the stack.
#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \
mvs_check_page (FILE, 8, 4); \
- fprintf (FILE, "\tSXXX\t13,=F'4'\n\tST\t%s,%d(13)\n", \
+ fprintf (FILE, "\tS\t13,=F'4'\n\tST\t%s,%d(13)\n", \
reg_names[REGNO], STACK_POINTER_OFFSET)
/* This is how to output an insn to pop a register from the stack.
#define ASM_OUTPUT_REG_POP(FILE, REGNO) \
mvs_check_page (FILE, 8, 0); \
- fprintf (FILE, "\tL\t%s,%d(13)\n\tLAXXX\t13,4(13)\n", \
+ fprintf (FILE, "\tL\t%s,%d(13)\n\tLA\t13,4(13)\n", \
reg_names[REGNO], STACK_POINTER_OFFSET)
-/* TBD: hack alert XXX these two float point macros print horribly
- incorrect things when run in cross-compiler mode. Thats's because
- in cross-compiler mode, the VALUE is not really a double. See below,
- in the ELF section, for the correct implementation. */
/* This is how to output an assembler line defining a `double' constant. */
#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
fprintf (FILE, "\tDC\tD'%.18G'\n", (VALUE))
{
/* an unsigned compare to zero is always zero/not-zero... */
mvs_check_page (0, 4, 4);
- return \"N %0,=X'000000FF'\";
+ return \"N %0,=XL4'000000FF'\";
}
mvs_check_page (0, 4, 0);
return \"CLI %0,0\";
{
/* an unsigned compare to zero is always zero/not-zero... */
mvs_check_page (0, 4, 4);
- return \"N %0,=X'000000FF'\";
+ return \"N %0,=XL4'000000FF'\";
}
mvs_check_page (0, 8, 0);
return \"SLL %0,24\;SRA %0,24\";
if (GET_CODE (operands[1]) == CONST_INT)
{
mvs_check_page (0, 4, 1);
- return \"CLM %0,1,=X'%X1'\";
+ return \"CLM %0,1,=XL1'%X1'\";
}
mvs_check_page (0, 4, 0);
return \"CLM %0,1,%1\";
if (REG_P (operands[1]))
{
mvs_check_page (0, 4, 1);
- return \"CLM %1,1,=X'%X0'\";
+ return \"CLM %1,1,=XL1'%X0'\";
}
mvs_check_page (0, 4, 0);
return \"CLI %1,%B0\";
if (GET_CODE (operands[1]) == CONST_INT)
{
mvs_check_page (0, 4, 1);
- return \"CLM %0,1,=X'%X1'\";
+ return \"CLM %0,1,=XL1'%X1'\";
}
if (!(REG_P (operands[1])))
{
else if (REG_P (operands[1]))
{
mvs_check_page (0, 4, 0);
- /* can't use stm otherwise stm r6,r7,0(r10,r13) can happen */
return \"STM %1,%N1,%0\";
- /* return \"ST %1,%0\;ST %N1,4+%0\"; */
}
mvs_check_page (0, 6, 0);
return \"MVC %O0(8,%R0),%W1\";
mvs_check_page (0, 4, 0);
return \"STD %1,%0\";
}
- else if (REG_P (operands[1]))
- {
- /* hack alert -- for some reason, %N0 doesn't work
- * when the mem ref is e.g. 168(r13,r1) ...
- * add 4 and pray for the best .. */
- mvs_check_page (0, 8, 0);
- return \"ST %1,%0\;ST %N1,4+%N0\";
- }
- /* this is almost certainly not what is desired, let it break ... */
- mvs_check_page (0, 8, 0);
- return \"xxxST %1,%0\;ST %N1,%N0\";
+ mvs_check_page (0, 4, 0);
+ return \"STM %1,%N1,%0\";
}"
[(set_attr "length" "8")]
)
if (REG_P (operands[0]))
{
mvs_check_page (0, 8, 0);
- return \"L %0,%1\;L %N0,4+%N1\";
+ return \"LM %0,%N0,%1\";
}
else if (REG_P (operands[1]))
{
mvs_check_page (0, 8, 0);
- return \"ST %1,%0\;ST %N1,4+%N0\";
+ return \"STM %1,%N1,%0\";
}
mvs_check_page (0, 6, 0);
- /* should never get here ... */
- return \"xxxxxxMVC %O0(8,%R0),%W1\";
+ return \"MVC %O0(8,%R0),%1\";
}"
[(set_attr "length" "8")]
)
return \"STM %1,%N1,%0\";
}
mvs_check_page (0, 6, 0);
- return \"MVC %O0(8,%R0),%W1\";
+ return \"MVC %O0(8,%R0),%1\";
}"
[(set_attr "length" "12")]
)
/* AND only sets zero/not-zero bits not the arithmetic bits ... */
CC_STATUS_INIT;
mvs_check_page (0, 4, 4);
- return \"N %1,=X'0000FFFF'\";
+ return \"N %1,=XL4'0000FFFF'\";
}"
[(set_attr "length" "4")]
)
/* AND only sets zero/not-zero bits not the arithmetic bits ... */
CC_STATUS_INIT;
mvs_check_page (0, 4, 4);
- return \"N %0,=X'000000FF'\";
+ return \"N %0,=XL4'000000FF'\";
}
if (GET_CODE (operands[1]) == CONST_INT)
{
/* AND only sets zero/not-zero bits not the arithmetic bits ... */
CC_STATUS_INIT;
mvs_check_page (0, 4, 4);
- return \"N %0,=X'000000FF'\";
+ return \"N %0,=XL4'000000FF'\";
}
if (GET_CODE (operands[1]) == CONST_INT)
{
;
; floatsidf2 instruction pattern(s).
;
+; LE/370 mode uses the float field of the TCA.
+;
(define_insn "floatsidf2"
[(set (match_operand:DF 0 "general_operand" "=f")
{
check_label_emit ();
CC_STATUS_INIT;
+#ifdef TARGET_ELF_ABI
+ mvs_check_page (0, 22, 12);
+ return \"MVC 140(4,13),=XL4'4E000000'\;ST %1,144(,13)\;XI 144(13),128\;LD %0,140(,13)\;SD %0,=XL8'4E00000080000000'\";
+#else
mvs_check_page (0, 16, 8);
- return \"ST %1,144(,13)\;XI 144(13),128\;LD %0,140(,13)\;SD %0,=XL8'4E00000080000000'\";
+ return \"ST %1,508(,12)\;XI 508(12),128\;LD %0,504(,12)\;SD %0,=XL8'4E00000080000000'\";
+#endif
}"
- [(set_attr "length" "16")]
+ [(set_attr "length" "22")]
)
;
/* XXX trouble. Below we generate some rtx's that model what
* is really supposed to happen with multiply on the 370/390
- * hardware, and that is all well & god. However, during optimization
+ * hardware, and that is all well & good. However, during optimization
* it can happen that the two operands are exchanged (after all,
* multiplication is commutitive), in which case the doubleword
* ends up in memory and everything is hosed. The gen_reg_rtx
return \"X %0,=F'-1'\";
}
mvs_check_page (0, 6, 4);
- return \"XC %O0(2,%R0),=X'FFFF'\";
+ return \"XC %O0(2,%R0),=XL4'FFFF'\";
}"
[(set_attr "length" "6")]
)
if (REG_P (operands[2]))
{
mvs_check_page (0, 8, 4);
- return \"N %0,=X'0000FFFF'\;SRL %0,0(%2)\";
+ return \"N %0,=XL4'0000FFFF'\;SRL %0,0(%2)\";
}
mvs_check_page (0, 8, 4);
- return \"N %0,=X'0000FFFF'\;SRL %0,%c2\";
+ return \"N %0,=XL4'0000FFFF'\;SRL %0,%c2\";
}"
[(set_attr "length" "8")]
)
CC_STATUS_INIT; /* AND sets the CC but not how we want it */
mvs_check_page (0, 8, 4);
if (REG_P (operands[2]))
- return \"N %0,=X'000000FF'\;SRL %0,0(%2)\";
- return \"N %0,=X'000000FF'\;SRL %0,%c2\";
+ return \"N %0,=XL4'000000FF'\;SRL %0,0(%2)\";
+ return \"N %0,=XL4'000000FF'\;SRL %0,%c2\";
}"
[(set_attr "length" "8")]
)