Wed Mar 23 12:52:43 2016 UTC ()
From Jake Hamby

For several years I've been eager to find the time to fix the bugs
in C++ exceptions on VAX to get them working on NetBSD, because
they穽e been broken for many years and it looked like only a few
changes were needed to get them working. Without C++ exceptions,
the NetBSD test suite can穰 be run. The good news is that I was
able to fix all the bugs in the VAX machine description to make
C++ exceptions work in GCC 4.8.5 (version unimportant). I wrote a
blog post explaining the bugs, with patches:

Here's a short summary, with the diffs in text form at the end of this email.

1) Replace #define FRAME_POINTER_CFA_OFFSET(FNDECL) 0 with #define
ARG_POINTER_CFA_OFFSET(FNDECL) 0 in gcc/config/vax/elf.h and
gcc/config/vax/vax.h. This changes the definition of __builtin_dwarf_cfa()
to return %ap instead of %fp, which correctly points to CFA.
Previously, the stack unwinder was crashing in _Unwind_RaiseException()
trying to follow bad pointers from the initial CFA.

2) Define EH_RETURN_DATA_REGNO(N) to include only R2 and R3 (instead
of R2-R5) and add code to vax_expand_prologue() in gcc/config/vax/vax.c
to add R2-R3 to the procedure entry mask but only if crtl->calls_eh_return
is set. This fixes a crash when the stack unwinder tried to write
values to R2 and R3 in the previous stack frame via
__builtin_eh_return_data_regno (0) and __builtin_eh_return_data_regno (1).

3) Removed definitions of EH_RETURN_STACKADJ_RTX and STARTING_FRAME_OFFSET
from gcc/config/vax/elf.h. It's not necessary to remember the stack
adjustment or to waste four bytes on every stack frame for a value
that's not needed. Also remove the suspicious changes in
gcc/config/vax/vax.md to the definitions of call_pop and call_value
regarding DW_CFA_GNU_args_size and EH unwinding. I reverted to the
previous versions from an older version of GCC, adding a few useful
comments that had been removed.

4) The last bug is the one I understand the least. I'm hoping
someone reading this can implement a correct fix. What I was seeing
after making all the previous changes to fix the other bugs is that
my test program failed to catch any exceptions, but instead returned
normally to the original return path.

Investigation revealed that GCC was correctly generating the
necessary move instruction to copy the second parameter passed to
__builtin_eh_return() into the return address, because
EH_RETURN_HANDLER_RTX had been defined correctly in config/vax/elf.h.
Here龝 what the call looks like in gcc/except.c:

#ifdef EH_RETURN_HANDLER_RTX
      rtx insn = emit_move_insn (EH_RETURN_HANDLER_RTX, crtl->eh.ehr_handler);
#else
      error ("__builtin_eh_return not supported on this target");
#endif

The problem was that the optimizer is deleting the final move
instruction when I compile with -O or higher. The assembly code at
-O0 (no optimization) generated for the __builtin_eh_return() call
at the end of _Unwind_RaiseException() looked like:

	calls $2,_Unwind_DebugHook
	movl -12(%fp),%r1
	movl %r1,16(%fp)
	ret
	.cfi_endproc

But then when I compiled with -O1 or -O2, all I saw was:

	calls $2,_Unwind_DebugHook
	ret
	.cfi_endproc

This was a mystery for me and I don穰 know enough about how the
final peephole optimizer works to really track down why it thinks
it can remove the move call to store the previous return address.
My workaround was to add a call to RTX_FRAME_RELATED_P (insn) = 1;
after the emit_move_insn() in gcc/except.c, which was used in
vax_expand_prologue() to mark the procedure entry mask.

By making this change, the optimizer no longer removes the call to
write the value to the previous stack pointer, but it adds an extra
line of .cfi exception info, which seems unnecessary since the code
is immediately going to return from the call and any adjustment
made by the DWARF stack unwinder will already have been done. Here龝
what the optimized code looks like with the patch (%r6 had been
loaded earlier):

	calls $2,_Unwind_DebugHook
	movl %r6,16(%fp)
	.cfi_offset 6, -36
	ret
	.cfi_endproc

With that final change, C++ exception handling now finally works
on NetBSD/vax, and I was able to successfully run the vast majority
of the tests in the ATF testsuite, which had been completely
inaccessible when I started due to both atf-run and atf-report
immediately dumping core due to the bad pointers that I fixed. Now
I have a bunch of new bugs to track down fixes for, but I think
this was the hardest set of problems that needed to be solved to
bring NetBSD on VAX up to the level of the other NetBSD ports.

Here are the diffs I have so far. They should apply to any recent
version of GCC (tested on GCC 4.8.5). With the exception of the
hack to gcc/except.c, the other diffs are ready to submit to NetBSD
as well as to upstream GCC. The fix I稘 like to see for the final
problem I discovered of the emit_move_insn() being deleted by the
optimizer would be another patch to one of the files in the
gcc/config/vax directory to explain to the optimizer that writing
to 16(%fp) is important and not something to be deleted from the
epilogue (perhaps it thinks it龝 writing to a local variable in
the frame that's about to be destroyed?).

I didn't see any indication that any other GCC ports required
anything special to tell the optimizer not to delete the move
instruction to EH_RETURN_HANDLER_RTX, so the other suspicion I have
is that there may be a bug specific to VAX's peephole optimizer or
related functions. Any ideas?


(christos)
diff -r1.1.1.3 -r1.2 src/external/gpl3/gcc/dist/gcc/except.c
diff -r1.4 -r1.5 src/external/gpl3/gcc/dist/gcc/config/vax/elf.h
diff -r1.11 -r1.12 src/external/gpl3/gcc/dist/gcc/config/vax/vax.c
diff -r1.5 -r1.6 src/external/gpl3/gcc/dist/gcc/config/vax/vax.h
diff -r1.9 -r1.10 src/external/gpl3/gcc/dist/gcc/config/vax/vax.md

cvs diff -r1.1.1.3 -r1.2 src/external/gpl3/gcc/dist/gcc/except.c (switch to unified diff)

--- src/external/gpl3/gcc/dist/gcc/except.c 2016/01/24 06:06:09 1.1.1.3
+++ src/external/gpl3/gcc/dist/gcc/except.c 2016/03/23 12:52:43 1.2
@@ -1292,1999 +1292,2000 @@ static void @@ -1292,1999 +1292,2000 @@ static void
1292sjlj_emit_dispatch_table (rtx_code_label *dispatch_label, int num_dispatch) 1292sjlj_emit_dispatch_table (rtx_code_label *dispatch_label, int num_dispatch)
1293{ 1293{
1294 machine_mode unwind_word_mode = targetm.unwind_word_mode (); 1294 machine_mode unwind_word_mode = targetm.unwind_word_mode ();
1295 machine_mode filter_mode = targetm.eh_return_filter_mode (); 1295 machine_mode filter_mode = targetm.eh_return_filter_mode ();
1296 eh_landing_pad lp; 1296 eh_landing_pad lp;
1297 rtx mem, fc, before, exc_ptr_reg, filter_reg; 1297 rtx mem, fc, before, exc_ptr_reg, filter_reg;
1298 rtx_insn *seq; 1298 rtx_insn *seq;
1299 rtx first_reachable_label; 1299 rtx first_reachable_label;
1300 basic_block bb; 1300 basic_block bb;
1301 eh_region r; 1301 eh_region r;
1302 edge e; 1302 edge e;
1303 int i, disp_index; 1303 int i, disp_index;
1304 vec<tree> dispatch_labels = vNULL; 1304 vec<tree> dispatch_labels = vNULL;
1305 1305
1306 fc = crtl->eh.sjlj_fc; 1306 fc = crtl->eh.sjlj_fc;
1307 1307
1308 start_sequence (); 1308 start_sequence ();
1309 1309
1310 emit_label (dispatch_label); 1310 emit_label (dispatch_label);
1311 1311
1312#ifndef DONT_USE_BUILTIN_SETJMP 1312#ifndef DONT_USE_BUILTIN_SETJMP
1313 expand_builtin_setjmp_receiver (dispatch_label); 1313 expand_builtin_setjmp_receiver (dispatch_label);
1314 1314
1315 /* The caller of expand_builtin_setjmp_receiver is responsible for 1315 /* The caller of expand_builtin_setjmp_receiver is responsible for
1316 making sure that the label doesn't vanish. The only other caller 1316 making sure that the label doesn't vanish. The only other caller
1317 is the expander for __builtin_setjmp_receiver, which places this 1317 is the expander for __builtin_setjmp_receiver, which places this
1318 label on the nonlocal_goto_label list. Since we're modeling these 1318 label on the nonlocal_goto_label list. Since we're modeling these
1319 CFG edges more exactly, we can use the forced_labels list instead. */ 1319 CFG edges more exactly, we can use the forced_labels list instead. */
1320 LABEL_PRESERVE_P (dispatch_label) = 1; 1320 LABEL_PRESERVE_P (dispatch_label) = 1;
1321 forced_labels 1321 forced_labels
1322 = gen_rtx_INSN_LIST (VOIDmode, dispatch_label, forced_labels); 1322 = gen_rtx_INSN_LIST (VOIDmode, dispatch_label, forced_labels);
1323#endif 1323#endif
1324 1324
1325 /* Load up exc_ptr and filter values from the function context. */ 1325 /* Load up exc_ptr and filter values from the function context. */
1326 mem = adjust_address (fc, unwind_word_mode, sjlj_fc_data_ofs); 1326 mem = adjust_address (fc, unwind_word_mode, sjlj_fc_data_ofs);
1327 if (unwind_word_mode != ptr_mode) 1327 if (unwind_word_mode != ptr_mode)
1328 { 1328 {
1329#ifdef POINTERS_EXTEND_UNSIGNED 1329#ifdef POINTERS_EXTEND_UNSIGNED
1330 mem = convert_memory_address (ptr_mode, mem); 1330 mem = convert_memory_address (ptr_mode, mem);
1331#else 1331#else
1332 mem = convert_to_mode (ptr_mode, mem, 0); 1332 mem = convert_to_mode (ptr_mode, mem, 0);
1333#endif 1333#endif
1334 } 1334 }
1335 exc_ptr_reg = force_reg (ptr_mode, mem); 1335 exc_ptr_reg = force_reg (ptr_mode, mem);
1336 1336
1337 mem = adjust_address (fc, unwind_word_mode, 1337 mem = adjust_address (fc, unwind_word_mode,
1338 sjlj_fc_data_ofs + GET_MODE_SIZE (unwind_word_mode)); 1338 sjlj_fc_data_ofs + GET_MODE_SIZE (unwind_word_mode));
1339 if (unwind_word_mode != filter_mode) 1339 if (unwind_word_mode != filter_mode)
1340 mem = convert_to_mode (filter_mode, mem, 0); 1340 mem = convert_to_mode (filter_mode, mem, 0);
1341 filter_reg = force_reg (filter_mode, mem); 1341 filter_reg = force_reg (filter_mode, mem);
1342 1342
1343 /* Jump to one of the directly reachable regions. */ 1343 /* Jump to one of the directly reachable regions. */
1344 1344
1345 disp_index = 0; 1345 disp_index = 0;
1346 first_reachable_label = NULL; 1346 first_reachable_label = NULL;
1347 1347
1348 /* If there's exactly one call site in the function, don't bother 1348 /* If there's exactly one call site in the function, don't bother
1349 generating a switch statement. */ 1349 generating a switch statement. */
1350 if (num_dispatch > 1) 1350 if (num_dispatch > 1)
1351 dispatch_labels.create (num_dispatch); 1351 dispatch_labels.create (num_dispatch);
1352 1352
1353 for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i) 1353 for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
1354 if (lp && lp->post_landing_pad) 1354 if (lp && lp->post_landing_pad)
1355 { 1355 {
1356 rtx_insn *seq2; 1356 rtx_insn *seq2;
1357 rtx label; 1357 rtx label;
1358 1358
1359 start_sequence (); 1359 start_sequence ();
1360 1360
1361 lp->landing_pad = dispatch_label; 1361 lp->landing_pad = dispatch_label;
1362 1362
1363 if (num_dispatch > 1) 1363 if (num_dispatch > 1)
1364 { 1364 {
1365 tree t_label, case_elt, t; 1365 tree t_label, case_elt, t;
1366 1366
1367 t_label = create_artificial_label (UNKNOWN_LOCATION); 1367 t_label = create_artificial_label (UNKNOWN_LOCATION);
1368 t = build_int_cst (integer_type_node, disp_index); 1368 t = build_int_cst (integer_type_node, disp_index);
1369 case_elt = build_case_label (t, NULL, t_label); 1369 case_elt = build_case_label (t, NULL, t_label);
1370 dispatch_labels.quick_push (case_elt); 1370 dispatch_labels.quick_push (case_elt);
1371 label = label_rtx (t_label); 1371 label = label_rtx (t_label);
1372 } 1372 }
1373 else 1373 else
1374 label = gen_label_rtx (); 1374 label = gen_label_rtx ();
1375 1375
1376 if (disp_index == 0) 1376 if (disp_index == 0)
1377 first_reachable_label = label; 1377 first_reachable_label = label;
1378 emit_label (label); 1378 emit_label (label);
1379 1379
1380 r = lp->region; 1380 r = lp->region;
1381 if (r->exc_ptr_reg) 1381 if (r->exc_ptr_reg)
1382 emit_move_insn (r->exc_ptr_reg, exc_ptr_reg); 1382 emit_move_insn (r->exc_ptr_reg, exc_ptr_reg);
1383 if (r->filter_reg) 1383 if (r->filter_reg)
1384 emit_move_insn (r->filter_reg, filter_reg); 1384 emit_move_insn (r->filter_reg, filter_reg);
1385 1385
1386 seq2 = get_insns (); 1386 seq2 = get_insns ();
1387 end_sequence (); 1387 end_sequence ();
1388 1388
1389 before = label_rtx (lp->post_landing_pad); 1389 before = label_rtx (lp->post_landing_pad);
1390 bb = emit_to_new_bb_before (seq2, before); 1390 bb = emit_to_new_bb_before (seq2, before);
1391 e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU); 1391 e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
1392 e->count = bb->count; 1392 e->count = bb->count;
1393 e->probability = REG_BR_PROB_BASE; 1393 e->probability = REG_BR_PROB_BASE;
1394 if (current_loops) 1394 if (current_loops)
1395 { 1395 {
1396 struct loop *loop = bb->next_bb->loop_father; 1396 struct loop *loop = bb->next_bb->loop_father;
1397 /* If we created a pre-header block, add the new block to the 1397 /* If we created a pre-header block, add the new block to the
1398 outer loop, otherwise to the loop itself. */ 1398 outer loop, otherwise to the loop itself. */
1399 if (bb->next_bb == loop->header) 1399 if (bb->next_bb == loop->header)
1400 add_bb_to_loop (bb, loop_outer (loop)); 1400 add_bb_to_loop (bb, loop_outer (loop));
1401 else 1401 else
1402 add_bb_to_loop (bb, loop); 1402 add_bb_to_loop (bb, loop);
1403 /* ??? For multiple dispatches we will end up with edges 1403 /* ??? For multiple dispatches we will end up with edges
1404 from the loop tree root into this loop, making it a 1404 from the loop tree root into this loop, making it a
1405 multiple-entry loop. Discard all affected loops. */ 1405 multiple-entry loop. Discard all affected loops. */
1406 if (num_dispatch > 1) 1406 if (num_dispatch > 1)
1407 { 1407 {
1408 for (loop = bb->loop_father; 1408 for (loop = bb->loop_father;
1409 loop_outer (loop); loop = loop_outer (loop)) 1409 loop_outer (loop); loop = loop_outer (loop))
1410 mark_loop_for_removal (loop); 1410 mark_loop_for_removal (loop);
1411 } 1411 }
1412 } 1412 }
1413 1413
1414 disp_index++; 1414 disp_index++;
1415 } 1415 }
1416 gcc_assert (disp_index == num_dispatch); 1416 gcc_assert (disp_index == num_dispatch);
1417 1417
1418 if (num_dispatch > 1) 1418 if (num_dispatch > 1)
1419 { 1419 {
1420 rtx disp = adjust_address (fc, TYPE_MODE (integer_type_node), 1420 rtx disp = adjust_address (fc, TYPE_MODE (integer_type_node),
1421 sjlj_fc_call_site_ofs); 1421 sjlj_fc_call_site_ofs);
1422 expand_sjlj_dispatch_table (disp, dispatch_labels); 1422 expand_sjlj_dispatch_table (disp, dispatch_labels);
1423 } 1423 }
1424 1424
1425 seq = get_insns (); 1425 seq = get_insns ();
1426 end_sequence (); 1426 end_sequence ();
1427 1427
1428 bb = emit_to_new_bb_before (seq, first_reachable_label); 1428 bb = emit_to_new_bb_before (seq, first_reachable_label);
1429 if (num_dispatch == 1) 1429 if (num_dispatch == 1)
1430 { 1430 {
1431 e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU); 1431 e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
1432 e->count = bb->count; 1432 e->count = bb->count;
1433 e->probability = REG_BR_PROB_BASE; 1433 e->probability = REG_BR_PROB_BASE;
1434 if (current_loops) 1434 if (current_loops)
1435 { 1435 {
1436 struct loop *loop = bb->next_bb->loop_father; 1436 struct loop *loop = bb->next_bb->loop_father;
1437 /* If we created a pre-header block, add the new block to the 1437 /* If we created a pre-header block, add the new block to the
1438 outer loop, otherwise to the loop itself. */ 1438 outer loop, otherwise to the loop itself. */
1439 if (bb->next_bb == loop->header) 1439 if (bb->next_bb == loop->header)
1440 add_bb_to_loop (bb, loop_outer (loop)); 1440 add_bb_to_loop (bb, loop_outer (loop));
1441 else 1441 else
1442 add_bb_to_loop (bb, loop); 1442 add_bb_to_loop (bb, loop);
1443 } 1443 }
1444 } 1444 }
1445 else 1445 else
1446 { 1446 {
1447 /* We are not wiring up edges here, but as the dispatcher call 1447 /* We are not wiring up edges here, but as the dispatcher call
1448 is at function begin simply associate the block with the 1448 is at function begin simply associate the block with the
1449 outermost (non-)loop. */ 1449 outermost (non-)loop. */
1450 if (current_loops) 1450 if (current_loops)
1451 add_bb_to_loop (bb, current_loops->tree_root); 1451 add_bb_to_loop (bb, current_loops->tree_root);
1452 } 1452 }
1453} 1453}
1454 1454
1455static void 1455static void
1456sjlj_build_landing_pads (void) 1456sjlj_build_landing_pads (void)
1457{ 1457{
1458 int num_dispatch; 1458 int num_dispatch;
1459 1459
1460 num_dispatch = vec_safe_length (cfun->eh->lp_array); 1460 num_dispatch = vec_safe_length (cfun->eh->lp_array);
1461 if (num_dispatch == 0) 1461 if (num_dispatch == 0)
1462 return; 1462 return;
1463 sjlj_lp_call_site_index.safe_grow_cleared (num_dispatch); 1463 sjlj_lp_call_site_index.safe_grow_cleared (num_dispatch);
1464 1464
1465 num_dispatch = sjlj_assign_call_site_values (); 1465 num_dispatch = sjlj_assign_call_site_values ();
1466 if (num_dispatch > 0) 1466 if (num_dispatch > 0)
1467 { 1467 {
1468 rtx_code_label *dispatch_label = gen_label_rtx (); 1468 rtx_code_label *dispatch_label = gen_label_rtx ();
1469 int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node, 1469 int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
1470 TYPE_MODE (sjlj_fc_type_node), 1470 TYPE_MODE (sjlj_fc_type_node),
1471 TYPE_ALIGN (sjlj_fc_type_node)); 1471 TYPE_ALIGN (sjlj_fc_type_node));
1472 crtl->eh.sjlj_fc 1472 crtl->eh.sjlj_fc
1473 = assign_stack_local (TYPE_MODE (sjlj_fc_type_node), 1473 = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
1474 int_size_in_bytes (sjlj_fc_type_node), 1474 int_size_in_bytes (sjlj_fc_type_node),
1475 align); 1475 align);
1476 1476
1477 sjlj_mark_call_sites (); 1477 sjlj_mark_call_sites ();
1478 sjlj_emit_function_enter (dispatch_label); 1478 sjlj_emit_function_enter (dispatch_label);
1479 sjlj_emit_dispatch_table (dispatch_label, num_dispatch); 1479 sjlj_emit_dispatch_table (dispatch_label, num_dispatch);
1480 sjlj_emit_function_exit (); 1480 sjlj_emit_function_exit ();
1481 } 1481 }
1482 1482
1483 /* If we do not have any landing pads, we may still need to register a 1483 /* If we do not have any landing pads, we may still need to register a
1484 personality routine and (empty) LSDA to handle must-not-throw regions. */ 1484 personality routine and (empty) LSDA to handle must-not-throw regions. */
1485 else if (function_needs_eh_personality (cfun) != eh_personality_none) 1485 else if (function_needs_eh_personality (cfun) != eh_personality_none)
1486 { 1486 {
1487 int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node, 1487 int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
1488 TYPE_MODE (sjlj_fc_type_node), 1488 TYPE_MODE (sjlj_fc_type_node),
1489 TYPE_ALIGN (sjlj_fc_type_node)); 1489 TYPE_ALIGN (sjlj_fc_type_node));
1490 crtl->eh.sjlj_fc 1490 crtl->eh.sjlj_fc
1491 = assign_stack_local (TYPE_MODE (sjlj_fc_type_node), 1491 = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
1492 int_size_in_bytes (sjlj_fc_type_node), 1492 int_size_in_bytes (sjlj_fc_type_node),
1493 align); 1493 align);
1494 1494
1495 sjlj_mark_call_sites (); 1495 sjlj_mark_call_sites ();
1496 sjlj_emit_function_enter (NULL); 1496 sjlj_emit_function_enter (NULL);
1497 sjlj_emit_function_exit (); 1497 sjlj_emit_function_exit ();
1498 } 1498 }
1499 1499
1500 sjlj_lp_call_site_index.release (); 1500 sjlj_lp_call_site_index.release ();
1501} 1501}
1502 1502
1503/* After initial rtl generation, call back to finish generating 1503/* After initial rtl generation, call back to finish generating
1504 exception support code. */ 1504 exception support code. */
1505 1505
1506void 1506void
1507finish_eh_generation (void) 1507finish_eh_generation (void)
1508{ 1508{
1509 basic_block bb; 1509 basic_block bb;
1510 1510
1511 /* Construct the landing pads. */ 1511 /* Construct the landing pads. */
1512 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) 1512 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
1513 sjlj_build_landing_pads (); 1513 sjlj_build_landing_pads ();
1514 else 1514 else
1515 dw2_build_landing_pads (); 1515 dw2_build_landing_pads ();
1516 break_superblocks (); 1516 break_superblocks ();
1517 1517
1518 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ 1518 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ
1519 /* Kludge for Alpha (see alpha_gp_save_rtx). */ 1519 /* Kludge for Alpha (see alpha_gp_save_rtx). */
1520 || single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->insns.r) 1520 || single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->insns.r)
1521 commit_edge_insertions (); 1521 commit_edge_insertions ();
1522 1522
1523 /* Redirect all EH edges from the post_landing_pad to the landing pad. */ 1523 /* Redirect all EH edges from the post_landing_pad to the landing pad. */
1524 FOR_EACH_BB_FN (bb, cfun) 1524 FOR_EACH_BB_FN (bb, cfun)
1525 { 1525 {
1526 eh_landing_pad lp; 1526 eh_landing_pad lp;
1527 edge_iterator ei; 1527 edge_iterator ei;
1528 edge e; 1528 edge e;
1529 1529
1530 lp = get_eh_landing_pad_from_rtx (BB_END (bb)); 1530 lp = get_eh_landing_pad_from_rtx (BB_END (bb));
1531 1531
1532 FOR_EACH_EDGE (e, ei, bb->succs) 1532 FOR_EACH_EDGE (e, ei, bb->succs)
1533 if (e->flags & EDGE_EH) 1533 if (e->flags & EDGE_EH)
1534 break; 1534 break;
1535 1535
1536 /* We should not have generated any new throwing insns during this 1536 /* We should not have generated any new throwing insns during this
1537 pass, and we should not have lost any EH edges, so we only need 1537 pass, and we should not have lost any EH edges, so we only need
1538 to handle two cases here: 1538 to handle two cases here:
1539 (1) reachable handler and an existing edge to post-landing-pad, 1539 (1) reachable handler and an existing edge to post-landing-pad,
1540 (2) no reachable handler and no edge. */ 1540 (2) no reachable handler and no edge. */
1541 gcc_assert ((lp != NULL) == (e != NULL)); 1541 gcc_assert ((lp != NULL) == (e != NULL));
1542 if (lp != NULL) 1542 if (lp != NULL)
1543 { 1543 {
1544 gcc_assert (BB_HEAD (e->dest) == label_rtx (lp->post_landing_pad)); 1544 gcc_assert (BB_HEAD (e->dest) == label_rtx (lp->post_landing_pad));
1545 1545
1546 redirect_edge_succ (e, BLOCK_FOR_INSN (lp->landing_pad)); 1546 redirect_edge_succ (e, BLOCK_FOR_INSN (lp->landing_pad));
1547 e->flags |= (CALL_P (BB_END (bb)) 1547 e->flags |= (CALL_P (BB_END (bb))
1548 ? EDGE_ABNORMAL | EDGE_ABNORMAL_CALL 1548 ? EDGE_ABNORMAL | EDGE_ABNORMAL_CALL
1549 : EDGE_ABNORMAL); 1549 : EDGE_ABNORMAL);
1550 } 1550 }
1551 } 1551 }
1552} 1552}
1553  1553
1554/* This section handles removing dead code for flow. */ 1554/* This section handles removing dead code for flow. */
1555 1555
1556void 1556void
1557remove_eh_landing_pad (eh_landing_pad lp) 1557remove_eh_landing_pad (eh_landing_pad lp)
1558{ 1558{
1559 eh_landing_pad *pp; 1559 eh_landing_pad *pp;
1560 1560
1561 for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp) 1561 for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
1562 continue; 1562 continue;
1563 *pp = lp->next_lp; 1563 *pp = lp->next_lp;
1564 1564
1565 if (lp->post_landing_pad) 1565 if (lp->post_landing_pad)
1566 EH_LANDING_PAD_NR (lp->post_landing_pad) = 0; 1566 EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
1567 (*cfun->eh->lp_array)[lp->index] = NULL; 1567 (*cfun->eh->lp_array)[lp->index] = NULL;
1568} 1568}
1569 1569
1570/* Splice the EH region at PP from the region tree. */ 1570/* Splice the EH region at PP from the region tree. */
1571 1571
1572static void 1572static void
1573remove_eh_handler_splicer (eh_region *pp) 1573remove_eh_handler_splicer (eh_region *pp)
1574{ 1574{
1575 eh_region region = *pp; 1575 eh_region region = *pp;
1576 eh_landing_pad lp; 1576 eh_landing_pad lp;
1577 1577
1578 for (lp = region->landing_pads; lp ; lp = lp->next_lp) 1578 for (lp = region->landing_pads; lp ; lp = lp->next_lp)
1579 { 1579 {
1580 if (lp->post_landing_pad) 1580 if (lp->post_landing_pad)
1581 EH_LANDING_PAD_NR (lp->post_landing_pad) = 0; 1581 EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
1582 (*cfun->eh->lp_array)[lp->index] = NULL; 1582 (*cfun->eh->lp_array)[lp->index] = NULL;
1583 } 1583 }
1584 1584
1585 if (region->inner) 1585 if (region->inner)
1586 { 1586 {
1587 eh_region p, outer; 1587 eh_region p, outer;
1588 outer = region->outer; 1588 outer = region->outer;
1589 1589
1590 *pp = p = region->inner; 1590 *pp = p = region->inner;
1591 do 1591 do
1592 { 1592 {
1593 p->outer = outer; 1593 p->outer = outer;
1594 pp = &p->next_peer; 1594 pp = &p->next_peer;
1595 p = *pp; 1595 p = *pp;
1596 } 1596 }
1597 while (p); 1597 while (p);
1598 } 1598 }
1599 *pp = region->next_peer; 1599 *pp = region->next_peer;
1600 1600
1601 (*cfun->eh->region_array)[region->index] = NULL; 1601 (*cfun->eh->region_array)[region->index] = NULL;
1602} 1602}
1603 1603
1604/* Splice a single EH region REGION from the region tree. 1604/* Splice a single EH region REGION from the region tree.
1605 1605
1606 To unlink REGION, we need to find the pointer to it with a relatively 1606 To unlink REGION, we need to find the pointer to it with a relatively
1607 expensive search in REGION's outer region. If you are going to 1607 expensive search in REGION's outer region. If you are going to
1608 remove a number of handlers, using remove_unreachable_eh_regions may 1608 remove a number of handlers, using remove_unreachable_eh_regions may
1609 be a better option. */ 1609 be a better option. */
1610 1610
1611void 1611void
1612remove_eh_handler (eh_region region) 1612remove_eh_handler (eh_region region)
1613{ 1613{
1614 eh_region *pp, *pp_start, p, outer; 1614 eh_region *pp, *pp_start, p, outer;
1615 1615
1616 outer = region->outer; 1616 outer = region->outer;
1617 if (outer) 1617 if (outer)
1618 pp_start = &outer->inner; 1618 pp_start = &outer->inner;
1619 else 1619 else
1620 pp_start = &cfun->eh->region_tree; 1620 pp_start = &cfun->eh->region_tree;
1621 for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp) 1621 for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
1622 continue; 1622 continue;
1623 1623
1624 remove_eh_handler_splicer (pp); 1624 remove_eh_handler_splicer (pp);
1625} 1625}
1626 1626
1627/* Worker for remove_unreachable_eh_regions. 1627/* Worker for remove_unreachable_eh_regions.
1628 PP is a pointer to the region to start a region tree depth-first 1628 PP is a pointer to the region to start a region tree depth-first
1629 search from. R_REACHABLE is the set of regions that have to be 1629 search from. R_REACHABLE is the set of regions that have to be
1630 preserved. */ 1630 preserved. */
1631 1631
1632static void 1632static void
1633remove_unreachable_eh_regions_worker (eh_region *pp, sbitmap r_reachable) 1633remove_unreachable_eh_regions_worker (eh_region *pp, sbitmap r_reachable)
1634{ 1634{
1635 while (*pp) 1635 while (*pp)
1636 { 1636 {
1637 eh_region region = *pp; 1637 eh_region region = *pp;
1638 remove_unreachable_eh_regions_worker (&region->inner, r_reachable); 1638 remove_unreachable_eh_regions_worker (&region->inner, r_reachable);
1639 if (!bitmap_bit_p (r_reachable, region->index)) 1639 if (!bitmap_bit_p (r_reachable, region->index))
1640 remove_eh_handler_splicer (pp); 1640 remove_eh_handler_splicer (pp);
1641 else 1641 else
1642 pp = &region->next_peer; 1642 pp = &region->next_peer;
1643 } 1643 }
1644} 1644}
1645 1645
1646/* Splice all EH regions *not* marked in R_REACHABLE from the region tree. 1646/* Splice all EH regions *not* marked in R_REACHABLE from the region tree.
1647 Do this by traversing the EH tree top-down and splice out regions that 1647 Do this by traversing the EH tree top-down and splice out regions that
1648 are not marked. By removing regions from the leaves, we avoid costly 1648 are not marked. By removing regions from the leaves, we avoid costly
1649 searches in the region tree. */ 1649 searches in the region tree. */
1650 1650
1651void 1651void
1652remove_unreachable_eh_regions (sbitmap r_reachable) 1652remove_unreachable_eh_regions (sbitmap r_reachable)
1653{ 1653{
1654 remove_unreachable_eh_regions_worker (&cfun->eh->region_tree, r_reachable); 1654 remove_unreachable_eh_regions_worker (&cfun->eh->region_tree, r_reachable);
1655} 1655}
1656 1656
1657/* Invokes CALLBACK for every exception handler landing pad label. 1657/* Invokes CALLBACK for every exception handler landing pad label.
1658 Only used by reload hackery; should not be used by new code. */ 1658 Only used by reload hackery; should not be used by new code. */
1659 1659
1660void 1660void
1661for_each_eh_label (void (*callback) (rtx)) 1661for_each_eh_label (void (*callback) (rtx))
1662{ 1662{
1663 eh_landing_pad lp; 1663 eh_landing_pad lp;
1664 int i; 1664 int i;
1665 1665
1666 for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i) 1666 for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
1667 { 1667 {
1668 if (lp) 1668 if (lp)
1669 { 1669 {
1670 rtx lab = lp->landing_pad; 1670 rtx lab = lp->landing_pad;
1671 if (lab && LABEL_P (lab)) 1671 if (lab && LABEL_P (lab))
1672 (*callback) (lab); 1672 (*callback) (lab);
1673 } 1673 }
1674 } 1674 }
1675} 1675}
1676  1676
1677/* Create the REG_EH_REGION note for INSN, given its ECF_FLAGS for a 1677/* Create the REG_EH_REGION note for INSN, given its ECF_FLAGS for a
1678 call insn. 1678 call insn.
1679 1679
1680 At the gimple level, we use LP_NR 1680 At the gimple level, we use LP_NR
1681 > 0 : The statement transfers to landing pad LP_NR 1681 > 0 : The statement transfers to landing pad LP_NR
1682 = 0 : The statement is outside any EH region 1682 = 0 : The statement is outside any EH region
1683 < 0 : The statement is within MUST_NOT_THROW region -LP_NR. 1683 < 0 : The statement is within MUST_NOT_THROW region -LP_NR.
1684 1684
1685 At the rtl level, we use LP_NR 1685 At the rtl level, we use LP_NR
1686 > 0 : The insn transfers to landing pad LP_NR 1686 > 0 : The insn transfers to landing pad LP_NR
1687 = 0 : The insn cannot throw 1687 = 0 : The insn cannot throw
1688 < 0 : The insn is within MUST_NOT_THROW region -LP_NR 1688 < 0 : The insn is within MUST_NOT_THROW region -LP_NR
1689 = INT_MIN : The insn cannot throw or execute a nonlocal-goto. 1689 = INT_MIN : The insn cannot throw or execute a nonlocal-goto.
1690 missing note: The insn is outside any EH region. 1690 missing note: The insn is outside any EH region.
1691 1691
1692 ??? This difference probably ought to be avoided. We could stand 1692 ??? This difference probably ought to be avoided. We could stand
1693 to record nothrow for arbitrary gimple statements, and so avoid 1693 to record nothrow for arbitrary gimple statements, and so avoid
1694 some moderately complex lookups in stmt_could_throw_p. Perhaps 1694 some moderately complex lookups in stmt_could_throw_p. Perhaps
1695 NOTHROW should be mapped on both sides to INT_MIN. Perhaps the 1695 NOTHROW should be mapped on both sides to INT_MIN. Perhaps the
1696 no-nonlocal-goto property should be recorded elsewhere as a bit 1696 no-nonlocal-goto property should be recorded elsewhere as a bit
1697 on the call_insn directly. Perhaps we should make more use of 1697 on the call_insn directly. Perhaps we should make more use of
1698 attaching the trees to call_insns (reachable via symbol_ref in 1698 attaching the trees to call_insns (reachable via symbol_ref in
1699 direct call cases) and just pull the data out of the trees. */ 1699 direct call cases) and just pull the data out of the trees. */
1700 1700
1701void 1701void
1702make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr) 1702make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr)
1703{ 1703{
1704 rtx value; 1704 rtx value;
1705 if (ecf_flags & ECF_NOTHROW) 1705 if (ecf_flags & ECF_NOTHROW)
1706 value = const0_rtx; 1706 value = const0_rtx;
1707 else if (lp_nr != 0) 1707 else if (lp_nr != 0)
1708 value = GEN_INT (lp_nr); 1708 value = GEN_INT (lp_nr);
1709 else 1709 else
1710 return; 1710 return;
1711 add_reg_note (insn, REG_EH_REGION, value); 1711 add_reg_note (insn, REG_EH_REGION, value);
1712} 1712}
1713 1713
1714/* Create a REG_EH_REGION note for a CALL_INSN that cannot throw 1714/* Create a REG_EH_REGION note for a CALL_INSN that cannot throw
1715 nor perform a non-local goto. Replace the region note if it 1715 nor perform a non-local goto. Replace the region note if it
1716 already exists. */ 1716 already exists. */
1717 1717
1718void 1718void
1719make_reg_eh_region_note_nothrow_nononlocal (rtx insn) 1719make_reg_eh_region_note_nothrow_nononlocal (rtx insn)
1720{ 1720{
1721 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); 1721 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1722 rtx intmin = GEN_INT (INT_MIN); 1722 rtx intmin = GEN_INT (INT_MIN);
1723 1723
1724 if (note != 0) 1724 if (note != 0)
1725 XEXP (note, 0) = intmin; 1725 XEXP (note, 0) = intmin;
1726 else 1726 else
1727 add_reg_note (insn, REG_EH_REGION, intmin); 1727 add_reg_note (insn, REG_EH_REGION, intmin);
1728} 1728}
1729 1729
1730/* Return true if INSN could throw, assuming no REG_EH_REGION note 1730/* Return true if INSN could throw, assuming no REG_EH_REGION note
1731 to the contrary. */ 1731 to the contrary. */
1732 1732
1733bool 1733bool
1734insn_could_throw_p (const_rtx insn) 1734insn_could_throw_p (const_rtx insn)
1735{ 1735{
1736 if (!flag_exceptions) 1736 if (!flag_exceptions)
1737 return false; 1737 return false;
1738 if (CALL_P (insn)) 1738 if (CALL_P (insn))
1739 return true; 1739 return true;
1740 if (INSN_P (insn) && cfun->can_throw_non_call_exceptions) 1740 if (INSN_P (insn) && cfun->can_throw_non_call_exceptions)
1741 return may_trap_p (PATTERN (insn)); 1741 return may_trap_p (PATTERN (insn));
1742 return false; 1742 return false;
1743} 1743}
1744 1744
1745/* Copy an REG_EH_REGION note to each insn that might throw beginning 1745/* Copy an REG_EH_REGION note to each insn that might throw beginning
1746 at FIRST and ending at LAST. NOTE_OR_INSN is either the source insn 1746 at FIRST and ending at LAST. NOTE_OR_INSN is either the source insn
1747 to look for a note, or the note itself. */ 1747 to look for a note, or the note itself. */
1748 1748
1749void 1749void
1750copy_reg_eh_region_note_forward (rtx note_or_insn, rtx_insn *first, rtx last) 1750copy_reg_eh_region_note_forward (rtx note_or_insn, rtx_insn *first, rtx last)
1751{ 1751{
1752 rtx_insn *insn; 1752 rtx_insn *insn;
1753 rtx note = note_or_insn; 1753 rtx note = note_or_insn;
1754 1754
1755 if (INSN_P (note_or_insn)) 1755 if (INSN_P (note_or_insn))
1756 { 1756 {
1757 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX); 1757 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
1758 if (note == NULL) 1758 if (note == NULL)
1759 return; 1759 return;
1760 } 1760 }
1761 note = XEXP (note, 0); 1761 note = XEXP (note, 0);
1762 1762
1763 for (insn = first; insn != last ; insn = NEXT_INSN (insn)) 1763 for (insn = first; insn != last ; insn = NEXT_INSN (insn))
1764 if (!find_reg_note (insn, REG_EH_REGION, NULL_RTX) 1764 if (!find_reg_note (insn, REG_EH_REGION, NULL_RTX)
1765 && insn_could_throw_p (insn)) 1765 && insn_could_throw_p (insn))
1766 add_reg_note (insn, REG_EH_REGION, note); 1766 add_reg_note (insn, REG_EH_REGION, note);
1767} 1767}
1768 1768
1769/* Likewise, but iterate backward. */ 1769/* Likewise, but iterate backward. */
1770 1770
1771void 1771void
1772copy_reg_eh_region_note_backward (rtx note_or_insn, rtx_insn *last, rtx first) 1772copy_reg_eh_region_note_backward (rtx note_or_insn, rtx_insn *last, rtx first)
1773{ 1773{
1774 rtx_insn *insn; 1774 rtx_insn *insn;
1775 rtx note = note_or_insn; 1775 rtx note = note_or_insn;
1776 1776
1777 if (INSN_P (note_or_insn)) 1777 if (INSN_P (note_or_insn))
1778 { 1778 {
1779 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX); 1779 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
1780 if (note == NULL) 1780 if (note == NULL)
1781 return; 1781 return;
1782 } 1782 }
1783 note = XEXP (note, 0); 1783 note = XEXP (note, 0);
1784 1784
1785 for (insn = last; insn != first; insn = PREV_INSN (insn)) 1785 for (insn = last; insn != first; insn = PREV_INSN (insn))
1786 if (insn_could_throw_p (insn)) 1786 if (insn_could_throw_p (insn))
1787 add_reg_note (insn, REG_EH_REGION, note); 1787 add_reg_note (insn, REG_EH_REGION, note);
1788} 1788}
1789 1789
1790 1790
1791/* Extract all EH information from INSN. Return true if the insn 1791/* Extract all EH information from INSN. Return true if the insn
1792 was marked NOTHROW. */ 1792 was marked NOTHROW. */
1793 1793
1794static bool 1794static bool
1795get_eh_region_and_lp_from_rtx (const_rtx insn, eh_region *pr, 1795get_eh_region_and_lp_from_rtx (const_rtx insn, eh_region *pr,
1796 eh_landing_pad *plp) 1796 eh_landing_pad *plp)
1797{ 1797{
1798 eh_landing_pad lp = NULL; 1798 eh_landing_pad lp = NULL;
1799 eh_region r = NULL; 1799 eh_region r = NULL;
1800 bool ret = false; 1800 bool ret = false;
1801 rtx note; 1801 rtx note;
1802 int lp_nr; 1802 int lp_nr;
1803 1803
1804 if (! INSN_P (insn)) 1804 if (! INSN_P (insn))
1805 goto egress; 1805 goto egress;
1806 1806
1807 if (NONJUMP_INSN_P (insn) 1807 if (NONJUMP_INSN_P (insn)
1808 && GET_CODE (PATTERN (insn)) == SEQUENCE) 1808 && GET_CODE (PATTERN (insn)) == SEQUENCE)
1809 insn = XVECEXP (PATTERN (insn), 0, 0); 1809 insn = XVECEXP (PATTERN (insn), 0, 0);
1810 1810
1811 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); 1811 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1812 if (!note) 1812 if (!note)
1813 { 1813 {
1814 ret = !insn_could_throw_p (insn); 1814 ret = !insn_could_throw_p (insn);
1815 goto egress; 1815 goto egress;
1816 } 1816 }
1817 1817
1818 lp_nr = INTVAL (XEXP (note, 0)); 1818 lp_nr = INTVAL (XEXP (note, 0));
1819 if (lp_nr == 0 || lp_nr == INT_MIN) 1819 if (lp_nr == 0 || lp_nr == INT_MIN)
1820 { 1820 {
1821 ret = true; 1821 ret = true;
1822 goto egress; 1822 goto egress;
1823 } 1823 }
1824 1824
1825 if (lp_nr < 0) 1825 if (lp_nr < 0)
1826 r = (*cfun->eh->region_array)[-lp_nr]; 1826 r = (*cfun->eh->region_array)[-lp_nr];
1827 else 1827 else
1828 { 1828 {
1829 lp = (*cfun->eh->lp_array)[lp_nr]; 1829 lp = (*cfun->eh->lp_array)[lp_nr];
1830 r = lp->region; 1830 r = lp->region;
1831 } 1831 }
1832 1832
1833 egress: 1833 egress:
1834 *plp = lp; 1834 *plp = lp;
1835 *pr = r; 1835 *pr = r;
1836 return ret; 1836 return ret;
1837} 1837}
1838 1838
1839/* Return the landing pad to which INSN may go, or NULL if it does not 1839/* Return the landing pad to which INSN may go, or NULL if it does not
1840 have a reachable landing pad within this function. */ 1840 have a reachable landing pad within this function. */
1841 1841
1842eh_landing_pad 1842eh_landing_pad
1843get_eh_landing_pad_from_rtx (const_rtx insn) 1843get_eh_landing_pad_from_rtx (const_rtx insn)
1844{ 1844{
1845 eh_landing_pad lp; 1845 eh_landing_pad lp;
1846 eh_region r; 1846 eh_region r;
1847 1847
1848 get_eh_region_and_lp_from_rtx (insn, &r, &lp); 1848 get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1849 return lp; 1849 return lp;
1850} 1850}
1851 1851
1852/* Return the region to which INSN may go, or NULL if it does not 1852/* Return the region to which INSN may go, or NULL if it does not
1853 have a reachable region within this function. */ 1853 have a reachable region within this function. */
1854 1854
1855eh_region 1855eh_region
1856get_eh_region_from_rtx (const_rtx insn) 1856get_eh_region_from_rtx (const_rtx insn)
1857{ 1857{
1858 eh_landing_pad lp; 1858 eh_landing_pad lp;
1859 eh_region r; 1859 eh_region r;
1860 1860
1861 get_eh_region_and_lp_from_rtx (insn, &r, &lp); 1861 get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1862 return r; 1862 return r;
1863} 1863}
1864 1864
1865/* Return true if INSN throws and is caught by something in this function. */ 1865/* Return true if INSN throws and is caught by something in this function. */
1866 1866
1867bool 1867bool
1868can_throw_internal (const_rtx insn) 1868can_throw_internal (const_rtx insn)
1869{ 1869{
1870 return get_eh_landing_pad_from_rtx (insn) != NULL; 1870 return get_eh_landing_pad_from_rtx (insn) != NULL;
1871} 1871}
1872 1872
1873/* Return true if INSN throws and escapes from the current function. */ 1873/* Return true if INSN throws and escapes from the current function. */
1874 1874
1875bool 1875bool
1876can_throw_external (const_rtx insn) 1876can_throw_external (const_rtx insn)
1877{ 1877{
1878 eh_landing_pad lp; 1878 eh_landing_pad lp;
1879 eh_region r; 1879 eh_region r;
1880 bool nothrow; 1880 bool nothrow;
1881 1881
1882 if (! INSN_P (insn)) 1882 if (! INSN_P (insn))
1883 return false; 1883 return false;
1884 1884
1885 if (NONJUMP_INSN_P (insn) 1885 if (NONJUMP_INSN_P (insn)
1886 && GET_CODE (PATTERN (insn)) == SEQUENCE) 1886 && GET_CODE (PATTERN (insn)) == SEQUENCE)
1887 { 1887 {
1888 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn)); 1888 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
1889 int i, n = seq->len (); 1889 int i, n = seq->len ();
1890 1890
1891 for (i = 0; i < n; i++) 1891 for (i = 0; i < n; i++)
1892 if (can_throw_external (seq->element (i))) 1892 if (can_throw_external (seq->element (i)))
1893 return true; 1893 return true;
1894 1894
1895 return false; 1895 return false;
1896 } 1896 }
1897 1897
1898 nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp); 1898 nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1899 1899
1900 /* If we can't throw, we obviously can't throw external. */ 1900 /* If we can't throw, we obviously can't throw external. */
1901 if (nothrow) 1901 if (nothrow)
1902 return false; 1902 return false;
1903 1903
1904 /* If we have an internal landing pad, then we're not external. */ 1904 /* If we have an internal landing pad, then we're not external. */
1905 if (lp != NULL) 1905 if (lp != NULL)
1906 return false; 1906 return false;
1907 1907
1908 /* If we're not within an EH region, then we are external. */ 1908 /* If we're not within an EH region, then we are external. */
1909 if (r == NULL) 1909 if (r == NULL)
1910 return true; 1910 return true;
1911 1911
1912 /* The only thing that ought to be left is MUST_NOT_THROW regions, 1912 /* The only thing that ought to be left is MUST_NOT_THROW regions,
1913 which don't always have landing pads. */ 1913 which don't always have landing pads. */
1914 gcc_assert (r->type == ERT_MUST_NOT_THROW); 1914 gcc_assert (r->type == ERT_MUST_NOT_THROW);
1915 return false; 1915 return false;
1916} 1916}
1917 1917
1918/* Return true if INSN cannot throw at all. */ 1918/* Return true if INSN cannot throw at all. */
1919 1919
1920bool 1920bool
1921insn_nothrow_p (const_rtx insn) 1921insn_nothrow_p (const_rtx insn)
1922{ 1922{
1923 eh_landing_pad lp; 1923 eh_landing_pad lp;
1924 eh_region r; 1924 eh_region r;
1925 1925
1926 if (! INSN_P (insn)) 1926 if (! INSN_P (insn))
1927 return true; 1927 return true;
1928 1928
1929 if (NONJUMP_INSN_P (insn) 1929 if (NONJUMP_INSN_P (insn)
1930 && GET_CODE (PATTERN (insn)) == SEQUENCE) 1930 && GET_CODE (PATTERN (insn)) == SEQUENCE)
1931 { 1931 {
1932 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn)); 1932 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
1933 int i, n = seq->len (); 1933 int i, n = seq->len ();
1934 1934
1935 for (i = 0; i < n; i++) 1935 for (i = 0; i < n; i++)
1936 if (!insn_nothrow_p (seq->element (i))) 1936 if (!insn_nothrow_p (seq->element (i)))
1937 return false; 1937 return false;
1938 1938
1939 return true; 1939 return true;
1940 } 1940 }
1941 1941
1942 return get_eh_region_and_lp_from_rtx (insn, &r, &lp); 1942 return get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1943} 1943}
1944 1944
1945/* Return true if INSN can perform a non-local goto. */ 1945/* Return true if INSN can perform a non-local goto. */
1946/* ??? This test is here in this file because it (ab)uses REG_EH_REGION. */ 1946/* ??? This test is here in this file because it (ab)uses REG_EH_REGION. */
1947 1947
1948bool 1948bool
1949can_nonlocal_goto (const_rtx insn) 1949can_nonlocal_goto (const_rtx insn)
1950{ 1950{
1951 if (nonlocal_goto_handler_labels && CALL_P (insn)) 1951 if (nonlocal_goto_handler_labels && CALL_P (insn))
1952 { 1952 {
1953 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); 1953 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1954 if (!note || INTVAL (XEXP (note, 0)) != INT_MIN) 1954 if (!note || INTVAL (XEXP (note, 0)) != INT_MIN)
1955 return true; 1955 return true;
1956 } 1956 }
1957 return false; 1957 return false;
1958} 1958}
1959  1959
1960/* Set TREE_NOTHROW and crtl->all_throwers_are_sibcalls. */ 1960/* Set TREE_NOTHROW and crtl->all_throwers_are_sibcalls. */
1961 1961
1962static unsigned int 1962static unsigned int
1963set_nothrow_function_flags (void) 1963set_nothrow_function_flags (void)
1964{ 1964{
1965 rtx_insn *insn; 1965 rtx_insn *insn;
1966 1966
1967 crtl->nothrow = 1; 1967 crtl->nothrow = 1;
1968 1968
1969 /* Assume crtl->all_throwers_are_sibcalls until we encounter 1969 /* Assume crtl->all_throwers_are_sibcalls until we encounter
1970 something that can throw an exception. We specifically exempt 1970 something that can throw an exception. We specifically exempt
1971 CALL_INSNs that are SIBLING_CALL_P, as these are really jumps, 1971 CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
1972 and can't throw. Most CALL_INSNs are not SIBLING_CALL_P, so this 1972 and can't throw. Most CALL_INSNs are not SIBLING_CALL_P, so this
1973 is optimistic. */ 1973 is optimistic. */
1974 1974
1975 crtl->all_throwers_are_sibcalls = 1; 1975 crtl->all_throwers_are_sibcalls = 1;
1976 1976
1977 /* If we don't know that this implementation of the function will 1977 /* If we don't know that this implementation of the function will
1978 actually be used, then we must not set TREE_NOTHROW, since 1978 actually be used, then we must not set TREE_NOTHROW, since
1979 callers must not assume that this function does not throw. */ 1979 callers must not assume that this function does not throw. */
1980 if (TREE_NOTHROW (current_function_decl)) 1980 if (TREE_NOTHROW (current_function_decl))
1981 return 0; 1981 return 0;
1982 1982
1983 if (! flag_exceptions) 1983 if (! flag_exceptions)
1984 return 0; 1984 return 0;
1985 1985
1986 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 1986 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1987 if (can_throw_external (insn)) 1987 if (can_throw_external (insn))
1988 { 1988 {
1989 crtl->nothrow = 0; 1989 crtl->nothrow = 0;
1990 1990
1991 if (!CALL_P (insn) || !SIBLING_CALL_P (insn)) 1991 if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
1992 { 1992 {
1993 crtl->all_throwers_are_sibcalls = 0; 1993 crtl->all_throwers_are_sibcalls = 0;
1994 return 0; 1994 return 0;
1995 } 1995 }
1996 } 1996 }
1997 1997
1998 if (crtl->nothrow 1998 if (crtl->nothrow
1999 && (cgraph_node::get (current_function_decl)->get_availability () 1999 && (cgraph_node::get (current_function_decl)->get_availability ()
2000 >= AVAIL_AVAILABLE)) 2000 >= AVAIL_AVAILABLE))
2001 { 2001 {
2002 struct cgraph_node *node = cgraph_node::get (current_function_decl); 2002 struct cgraph_node *node = cgraph_node::get (current_function_decl);
2003 struct cgraph_edge *e; 2003 struct cgraph_edge *e;
2004 for (e = node->callers; e; e = e->next_caller) 2004 for (e = node->callers; e; e = e->next_caller)
2005 e->can_throw_external = false; 2005 e->can_throw_external = false;
2006 node->set_nothrow_flag (true); 2006 node->set_nothrow_flag (true);
2007 2007
2008 if (dump_file) 2008 if (dump_file)
2009 fprintf (dump_file, "Marking function nothrow: %s\n\n", 2009 fprintf (dump_file, "Marking function nothrow: %s\n\n",
2010 current_function_name ()); 2010 current_function_name ());
2011 } 2011 }
2012 return 0; 2012 return 0;
2013} 2013}
2014 2014
2015namespace { 2015namespace {
2016 2016
2017const pass_data pass_data_set_nothrow_function_flags = 2017const pass_data pass_data_set_nothrow_function_flags =
2018{ 2018{
2019 RTL_PASS, /* type */ 2019 RTL_PASS, /* type */
2020 "nothrow", /* name */ 2020 "nothrow", /* name */
2021 OPTGROUP_NONE, /* optinfo_flags */ 2021 OPTGROUP_NONE, /* optinfo_flags */
2022 TV_NONE, /* tv_id */ 2022 TV_NONE, /* tv_id */
2023 0, /* properties_required */ 2023 0, /* properties_required */
2024 0, /* properties_provided */ 2024 0, /* properties_provided */
2025 0, /* properties_destroyed */ 2025 0, /* properties_destroyed */
2026 0, /* todo_flags_start */ 2026 0, /* todo_flags_start */
2027 0, /* todo_flags_finish */ 2027 0, /* todo_flags_finish */
2028}; 2028};
2029 2029
2030class pass_set_nothrow_function_flags : public rtl_opt_pass 2030class pass_set_nothrow_function_flags : public rtl_opt_pass
2031{ 2031{
2032public: 2032public:
2033 pass_set_nothrow_function_flags (gcc::context *ctxt) 2033 pass_set_nothrow_function_flags (gcc::context *ctxt)
2034 : rtl_opt_pass (pass_data_set_nothrow_function_flags, ctxt) 2034 : rtl_opt_pass (pass_data_set_nothrow_function_flags, ctxt)
2035 {} 2035 {}
2036 2036
2037 /* opt_pass methods: */ 2037 /* opt_pass methods: */
2038 virtual unsigned int execute (function *) 2038 virtual unsigned int execute (function *)
2039 { 2039 {
2040 return set_nothrow_function_flags (); 2040 return set_nothrow_function_flags ();
2041 } 2041 }
2042 2042
2043}; // class pass_set_nothrow_function_flags 2043}; // class pass_set_nothrow_function_flags
2044 2044
2045} // anon namespace 2045} // anon namespace
2046 2046
2047rtl_opt_pass * 2047rtl_opt_pass *
2048make_pass_set_nothrow_function_flags (gcc::context *ctxt) 2048make_pass_set_nothrow_function_flags (gcc::context *ctxt)
2049{ 2049{
2050 return new pass_set_nothrow_function_flags (ctxt); 2050 return new pass_set_nothrow_function_flags (ctxt);
2051} 2051}
2052 2052
2053  2053
2054/* Various hooks for unwind library. */ 2054/* Various hooks for unwind library. */
2055 2055
2056/* Expand the EH support builtin functions: 2056/* Expand the EH support builtin functions:
2057 __builtin_eh_pointer and __builtin_eh_filter. */ 2057 __builtin_eh_pointer and __builtin_eh_filter. */
2058 2058
2059static eh_region 2059static eh_region
2060expand_builtin_eh_common (tree region_nr_t) 2060expand_builtin_eh_common (tree region_nr_t)
2061{ 2061{
2062 HOST_WIDE_INT region_nr; 2062 HOST_WIDE_INT region_nr;
2063 eh_region region; 2063 eh_region region;
2064 2064
2065 gcc_assert (tree_fits_shwi_p (region_nr_t)); 2065 gcc_assert (tree_fits_shwi_p (region_nr_t));
2066 region_nr = tree_to_shwi (region_nr_t); 2066 region_nr = tree_to_shwi (region_nr_t);
2067 2067
2068 region = (*cfun->eh->region_array)[region_nr]; 2068 region = (*cfun->eh->region_array)[region_nr];
2069 2069
2070 /* ??? We shouldn't have been able to delete a eh region without 2070 /* ??? We shouldn't have been able to delete a eh region without
2071 deleting all the code that depended on it. */ 2071 deleting all the code that depended on it. */
2072 gcc_assert (region != NULL); 2072 gcc_assert (region != NULL);
2073 2073
2074 return region; 2074 return region;
2075} 2075}
2076 2076
2077/* Expand to the exc_ptr value from the given eh region. */ 2077/* Expand to the exc_ptr value from the given eh region. */
2078 2078
2079rtx 2079rtx
2080expand_builtin_eh_pointer (tree exp) 2080expand_builtin_eh_pointer (tree exp)
2081{ 2081{
2082 eh_region region 2082 eh_region region
2083 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0)); 2083 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
2084 if (region->exc_ptr_reg == NULL) 2084 if (region->exc_ptr_reg == NULL)
2085 region->exc_ptr_reg = gen_reg_rtx (ptr_mode); 2085 region->exc_ptr_reg = gen_reg_rtx (ptr_mode);
2086 return region->exc_ptr_reg; 2086 return region->exc_ptr_reg;
2087} 2087}
2088 2088
2089/* Expand to the filter value from the given eh region. */ 2089/* Expand to the filter value from the given eh region. */
2090 2090
2091rtx 2091rtx
2092expand_builtin_eh_filter (tree exp) 2092expand_builtin_eh_filter (tree exp)
2093{ 2093{
2094 eh_region region 2094 eh_region region
2095 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0)); 2095 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
2096 if (region->filter_reg == NULL) 2096 if (region->filter_reg == NULL)
2097 region->filter_reg = gen_reg_rtx (targetm.eh_return_filter_mode ()); 2097 region->filter_reg = gen_reg_rtx (targetm.eh_return_filter_mode ());
2098 return region->filter_reg; 2098 return region->filter_reg;
2099} 2099}
2100 2100
2101/* Copy the exc_ptr and filter values from one landing pad's registers 2101/* Copy the exc_ptr and filter values from one landing pad's registers
2102 to another. This is used to inline the resx statement. */ 2102 to another. This is used to inline the resx statement. */
2103 2103
2104rtx 2104rtx
2105expand_builtin_eh_copy_values (tree exp) 2105expand_builtin_eh_copy_values (tree exp)
2106{ 2106{
2107 eh_region dst 2107 eh_region dst
2108 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0)); 2108 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
2109 eh_region src 2109 eh_region src
2110 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 1)); 2110 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 1));
2111 machine_mode fmode = targetm.eh_return_filter_mode (); 2111 machine_mode fmode = targetm.eh_return_filter_mode ();
2112 2112
2113 if (dst->exc_ptr_reg == NULL) 2113 if (dst->exc_ptr_reg == NULL)
2114 dst->exc_ptr_reg = gen_reg_rtx (ptr_mode); 2114 dst->exc_ptr_reg = gen_reg_rtx (ptr_mode);
2115 if (src->exc_ptr_reg == NULL) 2115 if (src->exc_ptr_reg == NULL)
2116 src->exc_ptr_reg = gen_reg_rtx (ptr_mode); 2116 src->exc_ptr_reg = gen_reg_rtx (ptr_mode);
2117 2117
2118 if (dst->filter_reg == NULL) 2118 if (dst->filter_reg == NULL)
2119 dst->filter_reg = gen_reg_rtx (fmode); 2119 dst->filter_reg = gen_reg_rtx (fmode);
2120 if (src->filter_reg == NULL) 2120 if (src->filter_reg == NULL)
2121 src->filter_reg = gen_reg_rtx (fmode); 2121 src->filter_reg = gen_reg_rtx (fmode);
2122 2122
2123 emit_move_insn (dst->exc_ptr_reg, src->exc_ptr_reg); 2123 emit_move_insn (dst->exc_ptr_reg, src->exc_ptr_reg);
2124 emit_move_insn (dst->filter_reg, src->filter_reg); 2124 emit_move_insn (dst->filter_reg, src->filter_reg);
2125 2125
2126 return const0_rtx; 2126 return const0_rtx;
2127} 2127}
2128 2128
2129/* Do any necessary initialization to access arbitrary stack frames. 2129/* Do any necessary initialization to access arbitrary stack frames.
2130 On the SPARC, this means flushing the register windows. */ 2130 On the SPARC, this means flushing the register windows. */
2131 2131
2132void 2132void
2133expand_builtin_unwind_init (void) 2133expand_builtin_unwind_init (void)
2134{ 2134{
2135 /* Set this so all the registers get saved in our frame; we need to be 2135 /* Set this so all the registers get saved in our frame; we need to be
2136 able to copy the saved values for any registers from frames we unwind. */ 2136 able to copy the saved values for any registers from frames we unwind. */
2137 crtl->saves_all_registers = 1; 2137 crtl->saves_all_registers = 1;
2138 2138
2139#ifdef SETUP_FRAME_ADDRESSES 2139#ifdef SETUP_FRAME_ADDRESSES
2140 SETUP_FRAME_ADDRESSES (); 2140 SETUP_FRAME_ADDRESSES ();
2141#endif 2141#endif
2142} 2142}
2143 2143
2144/* Map a non-negative number to an eh return data register number; expands 2144/* Map a non-negative number to an eh return data register number; expands
2145 to -1 if no return data register is associated with the input number. 2145 to -1 if no return data register is associated with the input number.
2146 At least the inputs 0 and 1 must be mapped; the target may provide more. */ 2146 At least the inputs 0 and 1 must be mapped; the target may provide more. */
2147 2147
2148rtx 2148rtx
2149expand_builtin_eh_return_data_regno (tree exp) 2149expand_builtin_eh_return_data_regno (tree exp)
2150{ 2150{
2151 tree which = CALL_EXPR_ARG (exp, 0); 2151 tree which = CALL_EXPR_ARG (exp, 0);
2152 unsigned HOST_WIDE_INT iwhich; 2152 unsigned HOST_WIDE_INT iwhich;
2153 2153
2154 if (TREE_CODE (which) != INTEGER_CST) 2154 if (TREE_CODE (which) != INTEGER_CST)
2155 { 2155 {
2156 error ("argument of %<__builtin_eh_return_regno%> must be constant"); 2156 error ("argument of %<__builtin_eh_return_regno%> must be constant");
2157 return constm1_rtx; 2157 return constm1_rtx;
2158 } 2158 }
2159 2159
2160 iwhich = tree_to_uhwi (which); 2160 iwhich = tree_to_uhwi (which);
2161 iwhich = EH_RETURN_DATA_REGNO (iwhich); 2161 iwhich = EH_RETURN_DATA_REGNO (iwhich);
2162 if (iwhich == INVALID_REGNUM) 2162 if (iwhich == INVALID_REGNUM)
2163 return constm1_rtx; 2163 return constm1_rtx;
2164 2164
2165#ifdef DWARF_FRAME_REGNUM 2165#ifdef DWARF_FRAME_REGNUM
2166 iwhich = DWARF_FRAME_REGNUM (iwhich); 2166 iwhich = DWARF_FRAME_REGNUM (iwhich);
2167#else 2167#else
2168 iwhich = DBX_REGISTER_NUMBER (iwhich); 2168 iwhich = DBX_REGISTER_NUMBER (iwhich);
2169#endif 2169#endif
2170 2170
2171 return GEN_INT (iwhich); 2171 return GEN_INT (iwhich);
2172} 2172}
2173 2173
2174/* Given a value extracted from the return address register or stack slot, 2174/* Given a value extracted from the return address register or stack slot,
2175 return the actual address encoded in that value. */ 2175 return the actual address encoded in that value. */
2176 2176
2177rtx 2177rtx
2178expand_builtin_extract_return_addr (tree addr_tree) 2178expand_builtin_extract_return_addr (tree addr_tree)
2179{ 2179{
2180 rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL); 2180 rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2181 2181
2182 if (GET_MODE (addr) != Pmode 2182 if (GET_MODE (addr) != Pmode
2183 && GET_MODE (addr) != VOIDmode) 2183 && GET_MODE (addr) != VOIDmode)
2184 { 2184 {
2185#ifdef POINTERS_EXTEND_UNSIGNED 2185#ifdef POINTERS_EXTEND_UNSIGNED
2186 addr = convert_memory_address (Pmode, addr); 2186 addr = convert_memory_address (Pmode, addr);
2187#else 2187#else
2188 addr = convert_to_mode (Pmode, addr, 0); 2188 addr = convert_to_mode (Pmode, addr, 0);
2189#endif 2189#endif
2190 } 2190 }
2191 2191
2192 /* First mask out any unwanted bits. */ 2192 /* First mask out any unwanted bits. */
2193#ifdef MASK_RETURN_ADDR 2193#ifdef MASK_RETURN_ADDR
2194 expand_and (Pmode, addr, MASK_RETURN_ADDR, addr); 2194 expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
2195#endif 2195#endif
2196 2196
2197 /* Then adjust to find the real return address. */ 2197 /* Then adjust to find the real return address. */
2198#if defined (RETURN_ADDR_OFFSET) 2198#if defined (RETURN_ADDR_OFFSET)
2199 addr = plus_constant (Pmode, addr, RETURN_ADDR_OFFSET); 2199 addr = plus_constant (Pmode, addr, RETURN_ADDR_OFFSET);
2200#endif 2200#endif
2201 2201
2202 return addr; 2202 return addr;
2203} 2203}
2204 2204
2205/* Given an actual address in addr_tree, do any necessary encoding 2205/* Given an actual address in addr_tree, do any necessary encoding
2206 and return the value to be stored in the return address register or 2206 and return the value to be stored in the return address register or
2207 stack slot so the epilogue will return to that address. */ 2207 stack slot so the epilogue will return to that address. */
2208 2208
2209rtx 2209rtx
2210expand_builtin_frob_return_addr (tree addr_tree) 2210expand_builtin_frob_return_addr (tree addr_tree)
2211{ 2211{
2212 rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL); 2212 rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
2213 2213
2214 addr = convert_memory_address (Pmode, addr); 2214 addr = convert_memory_address (Pmode, addr);
2215 2215
2216#ifdef RETURN_ADDR_OFFSET 2216#ifdef RETURN_ADDR_OFFSET
2217 addr = force_reg (Pmode, addr); 2217 addr = force_reg (Pmode, addr);
2218 addr = plus_constant (Pmode, addr, -RETURN_ADDR_OFFSET); 2218 addr = plus_constant (Pmode, addr, -RETURN_ADDR_OFFSET);
2219#endif 2219#endif
2220 2220
2221 return addr; 2221 return addr;
2222} 2222}
2223 2223
2224/* Set up the epilogue with the magic bits we'll need to return to the 2224/* Set up the epilogue with the magic bits we'll need to return to the
2225 exception handler. */ 2225 exception handler. */
2226 2226
2227void 2227void
2228expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED, 2228expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
2229 tree handler_tree) 2229 tree handler_tree)
2230{ 2230{
2231 rtx tmp; 2231 rtx tmp;
2232 2232
2233#ifdef EH_RETURN_STACKADJ_RTX 2233#ifdef EH_RETURN_STACKADJ_RTX
2234 tmp = expand_expr (stackadj_tree, crtl->eh.ehr_stackadj, 2234 tmp = expand_expr (stackadj_tree, crtl->eh.ehr_stackadj,
2235 VOIDmode, EXPAND_NORMAL); 2235 VOIDmode, EXPAND_NORMAL);
2236 tmp = convert_memory_address (Pmode, tmp); 2236 tmp = convert_memory_address (Pmode, tmp);
2237 if (!crtl->eh.ehr_stackadj) 2237 if (!crtl->eh.ehr_stackadj)
2238 crtl->eh.ehr_stackadj = copy_addr_to_reg (tmp); 2238 crtl->eh.ehr_stackadj = copy_addr_to_reg (tmp);
2239 else if (tmp != crtl->eh.ehr_stackadj) 2239 else if (tmp != crtl->eh.ehr_stackadj)
2240 emit_move_insn (crtl->eh.ehr_stackadj, tmp); 2240 emit_move_insn (crtl->eh.ehr_stackadj, tmp);
2241#endif 2241#endif
2242 2242
2243 tmp = expand_expr (handler_tree, crtl->eh.ehr_handler, 2243 tmp = expand_expr (handler_tree, crtl->eh.ehr_handler,
2244 VOIDmode, EXPAND_NORMAL); 2244 VOIDmode, EXPAND_NORMAL);
2245 tmp = convert_memory_address (Pmode, tmp); 2245 tmp = convert_memory_address (Pmode, tmp);
2246 if (!crtl->eh.ehr_handler) 2246 if (!crtl->eh.ehr_handler)
2247 crtl->eh.ehr_handler = copy_addr_to_reg (tmp); 2247 crtl->eh.ehr_handler = copy_addr_to_reg (tmp);
2248 else if (tmp != crtl->eh.ehr_handler) 2248 else if (tmp != crtl->eh.ehr_handler)
2249 emit_move_insn (crtl->eh.ehr_handler, tmp); 2249 emit_move_insn (crtl->eh.ehr_handler, tmp);
2250 2250
2251 if (!crtl->eh.ehr_label) 2251 if (!crtl->eh.ehr_label)
2252 crtl->eh.ehr_label = gen_label_rtx (); 2252 crtl->eh.ehr_label = gen_label_rtx ();
2253 emit_jump (crtl->eh.ehr_label); 2253 emit_jump (crtl->eh.ehr_label);
2254} 2254}
2255 2255
2256/* Expand __builtin_eh_return. This exit path from the function loads up 2256/* Expand __builtin_eh_return. This exit path from the function loads up
2257 the eh return data registers, adjusts the stack, and branches to a 2257 the eh return data registers, adjusts the stack, and branches to a
2258 given PC other than the normal return address. */ 2258 given PC other than the normal return address. */
2259 2259
2260void 2260void
2261expand_eh_return (void) 2261expand_eh_return (void)
2262{ 2262{
2263 rtx_code_label *around_label; 2263 rtx_code_label *around_label;
2264 2264
2265 if (! crtl->eh.ehr_label) 2265 if (! crtl->eh.ehr_label)
2266 return; 2266 return;
2267 2267
2268 crtl->calls_eh_return = 1; 2268 crtl->calls_eh_return = 1;
2269 2269
2270#ifdef EH_RETURN_STACKADJ_RTX 2270#ifdef EH_RETURN_STACKADJ_RTX
2271 emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx); 2271 emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx);
2272#endif 2272#endif
2273 2273
2274 around_label = gen_label_rtx (); 2274 around_label = gen_label_rtx ();
2275 emit_jump (around_label); 2275 emit_jump (around_label);
2276 2276
2277 emit_label (crtl->eh.ehr_label); 2277 emit_label (crtl->eh.ehr_label);
2278 clobber_return_register (); 2278 clobber_return_register ();
2279 2279
2280#ifdef EH_RETURN_STACKADJ_RTX 2280#ifdef EH_RETURN_STACKADJ_RTX
2281 emit_move_insn (EH_RETURN_STACKADJ_RTX, crtl->eh.ehr_stackadj); 2281 emit_move_insn (EH_RETURN_STACKADJ_RTX, crtl->eh.ehr_stackadj);
2282#endif 2282#endif
2283 2283
2284#ifdef HAVE_eh_return 2284#ifdef HAVE_eh_return
2285 if (HAVE_eh_return) 2285 if (HAVE_eh_return)
2286 emit_insn (gen_eh_return (crtl->eh.ehr_handler)); 2286 emit_insn (gen_eh_return (crtl->eh.ehr_handler));
2287 else 2287 else
2288#endif 2288#endif
2289 { 2289 {
2290#ifdef EH_RETURN_HANDLER_RTX 2290#ifdef EH_RETURN_HANDLER_RTX
2291 emit_move_insn (EH_RETURN_HANDLER_RTX, crtl->eh.ehr_handler); 2291 rtx insn = emit_move_insn (EH_RETURN_HANDLER_RTX, crtl->eh.ehr_handler);
 2292 RTX_FRAME_RELATED_P (insn) = 1;
2292#else 2293#else
2293 error ("__builtin_eh_return not supported on this target"); 2294 error ("__builtin_eh_return not supported on this target");
2294#endif 2295#endif
2295 } 2296 }
2296 2297
2297 emit_label (around_label); 2298 emit_label (around_label);
2298} 2299}
2299 2300
2300/* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by 2301/* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by
2301 POINTERS_EXTEND_UNSIGNED and return it. */ 2302 POINTERS_EXTEND_UNSIGNED and return it. */
2302 2303
2303rtx 2304rtx
2304expand_builtin_extend_pointer (tree addr_tree) 2305expand_builtin_extend_pointer (tree addr_tree)
2305{ 2306{
2306 rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL); 2307 rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
2307 int extend; 2308 int extend;
2308 2309
2309#ifdef POINTERS_EXTEND_UNSIGNED 2310#ifdef POINTERS_EXTEND_UNSIGNED
2310 extend = POINTERS_EXTEND_UNSIGNED; 2311 extend = POINTERS_EXTEND_UNSIGNED;
2311#else 2312#else
2312 /* The previous EH code did an unsigned extend by default, so we do this also 2313 /* The previous EH code did an unsigned extend by default, so we do this also
2313 for consistency. */ 2314 for consistency. */
2314 extend = 1; 2315 extend = 1;
2315#endif 2316#endif
2316 2317
2317 return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend); 2318 return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend);
2318} 2319}
2319  2320
2320static int 2321static int
2321add_action_record (action_hash_type *ar_hash, int filter, int next) 2322add_action_record (action_hash_type *ar_hash, int filter, int next)
2322{ 2323{
2323 struct action_record **slot, *new_ar, tmp; 2324 struct action_record **slot, *new_ar, tmp;
2324 2325
2325 tmp.filter = filter; 2326 tmp.filter = filter;
2326 tmp.next = next; 2327 tmp.next = next;
2327 slot = ar_hash->find_slot (&tmp, INSERT); 2328 slot = ar_hash->find_slot (&tmp, INSERT);
2328 2329
2329 if ((new_ar = *slot) == NULL) 2330 if ((new_ar = *slot) == NULL)
2330 { 2331 {
2331 new_ar = XNEW (struct action_record); 2332 new_ar = XNEW (struct action_record);
2332 new_ar->offset = crtl->eh.action_record_data->length () + 1; 2333 new_ar->offset = crtl->eh.action_record_data->length () + 1;
2333 new_ar->filter = filter; 2334 new_ar->filter = filter;
2334 new_ar->next = next; 2335 new_ar->next = next;
2335 *slot = new_ar; 2336 *slot = new_ar;
2336 2337
2337 /* The filter value goes in untouched. The link to the next 2338 /* The filter value goes in untouched. The link to the next
2338 record is a "self-relative" byte offset, or zero to indicate 2339 record is a "self-relative" byte offset, or zero to indicate
2339 that there is no next record. So convert the absolute 1 based 2340 that there is no next record. So convert the absolute 1 based
2340 indices we've been carrying around into a displacement. */ 2341 indices we've been carrying around into a displacement. */
2341 2342
2342 push_sleb128 (&crtl->eh.action_record_data, filter); 2343 push_sleb128 (&crtl->eh.action_record_data, filter);
2343 if (next) 2344 if (next)
2344 next -= crtl->eh.action_record_data->length () + 1; 2345 next -= crtl->eh.action_record_data->length () + 1;
2345 push_sleb128 (&crtl->eh.action_record_data, next); 2346 push_sleb128 (&crtl->eh.action_record_data, next);
2346 } 2347 }
2347 2348
2348 return new_ar->offset; 2349 return new_ar->offset;
2349} 2350}
2350 2351
2351static int 2352static int
2352collect_one_action_chain (action_hash_type *ar_hash, eh_region region) 2353collect_one_action_chain (action_hash_type *ar_hash, eh_region region)
2353{ 2354{
2354 int next; 2355 int next;
2355 2356
2356 /* If we've reached the top of the region chain, then we have 2357 /* If we've reached the top of the region chain, then we have
2357 no actions, and require no landing pad. */ 2358 no actions, and require no landing pad. */
2358 if (region == NULL) 2359 if (region == NULL)
2359 return -1; 2360 return -1;
2360 2361
2361 switch (region->type) 2362 switch (region->type)
2362 { 2363 {
2363 case ERT_CLEANUP: 2364 case ERT_CLEANUP:
2364 { 2365 {
2365 eh_region r; 2366 eh_region r;
2366 /* A cleanup adds a zero filter to the beginning of the chain, but 2367 /* A cleanup adds a zero filter to the beginning of the chain, but
2367 there are special cases to look out for. If there are *only* 2368 there are special cases to look out for. If there are *only*
2368 cleanups along a path, then it compresses to a zero action. 2369 cleanups along a path, then it compresses to a zero action.
2369 Further, if there are multiple cleanups along a path, we only 2370 Further, if there are multiple cleanups along a path, we only
2370 need to represent one of them, as that is enough to trigger 2371 need to represent one of them, as that is enough to trigger
2371 entry to the landing pad at runtime. */ 2372 entry to the landing pad at runtime. */
2372 next = collect_one_action_chain (ar_hash, region->outer); 2373 next = collect_one_action_chain (ar_hash, region->outer);
2373 if (next <= 0) 2374 if (next <= 0)
2374 return 0; 2375 return 0;
2375 for (r = region->outer; r ; r = r->outer) 2376 for (r = region->outer; r ; r = r->outer)
2376 if (r->type == ERT_CLEANUP) 2377 if (r->type == ERT_CLEANUP)
2377 return next; 2378 return next;
2378 return add_action_record (ar_hash, 0, next); 2379 return add_action_record (ar_hash, 0, next);
2379 } 2380 }
2380 2381
2381 case ERT_TRY: 2382 case ERT_TRY:
2382 { 2383 {
2383 eh_catch c; 2384 eh_catch c;
2384 2385
2385 /* Process the associated catch regions in reverse order. 2386 /* Process the associated catch regions in reverse order.
2386 If there's a catch-all handler, then we don't need to 2387 If there's a catch-all handler, then we don't need to
2387 search outer regions. Use a magic -3 value to record 2388 search outer regions. Use a magic -3 value to record
2388 that we haven't done the outer search. */ 2389 that we haven't done the outer search. */
2389 next = -3; 2390 next = -3;
2390 for (c = region->u.eh_try.last_catch; c ; c = c->prev_catch) 2391 for (c = region->u.eh_try.last_catch; c ; c = c->prev_catch)
2391 { 2392 {
2392 if (c->type_list == NULL) 2393 if (c->type_list == NULL)
2393 { 2394 {
2394 /* Retrieve the filter from the head of the filter list 2395 /* Retrieve the filter from the head of the filter list
2395 where we have stored it (see assign_filter_values). */ 2396 where we have stored it (see assign_filter_values). */
2396 int filter = TREE_INT_CST_LOW (TREE_VALUE (c->filter_list)); 2397 int filter = TREE_INT_CST_LOW (TREE_VALUE (c->filter_list));
2397 next = add_action_record (ar_hash, filter, 0); 2398 next = add_action_record (ar_hash, filter, 0);
2398 } 2399 }
2399 else 2400 else
2400 { 2401 {
2401 /* Once the outer search is done, trigger an action record for 2402 /* Once the outer search is done, trigger an action record for
2402 each filter we have. */ 2403 each filter we have. */
2403 tree flt_node; 2404 tree flt_node;
2404 2405
2405 if (next == -3) 2406 if (next == -3)
2406 { 2407 {
2407 next = collect_one_action_chain (ar_hash, region->outer); 2408 next = collect_one_action_chain (ar_hash, region->outer);
2408 2409
2409 /* If there is no next action, terminate the chain. */ 2410 /* If there is no next action, terminate the chain. */
2410 if (next == -1) 2411 if (next == -1)
2411 next = 0; 2412 next = 0;
2412 /* If all outer actions are cleanups or must_not_throw, 2413 /* If all outer actions are cleanups or must_not_throw,
2413 we'll have no action record for it, since we had wanted 2414 we'll have no action record for it, since we had wanted
2414 to encode these states in the call-site record directly. 2415 to encode these states in the call-site record directly.
2415 Add a cleanup action to the chain to catch these. */ 2416 Add a cleanup action to the chain to catch these. */
2416 else if (next <= 0) 2417 else if (next <= 0)
2417 next = add_action_record (ar_hash, 0, 0); 2418 next = add_action_record (ar_hash, 0, 0);
2418 } 2419 }
2419 2420
2420 flt_node = c->filter_list; 2421 flt_node = c->filter_list;
2421 for (; flt_node; flt_node = TREE_CHAIN (flt_node)) 2422 for (; flt_node; flt_node = TREE_CHAIN (flt_node))
2422 { 2423 {
2423 int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node)); 2424 int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
2424 next = add_action_record (ar_hash, filter, next); 2425 next = add_action_record (ar_hash, filter, next);
2425 } 2426 }
2426 } 2427 }
2427 } 2428 }
2428 return next; 2429 return next;
2429 } 2430 }
2430 2431
2431 case ERT_ALLOWED_EXCEPTIONS: 2432 case ERT_ALLOWED_EXCEPTIONS:
2432 /* An exception specification adds its filter to the 2433 /* An exception specification adds its filter to the
2433 beginning of the chain. */ 2434 beginning of the chain. */
2434 next = collect_one_action_chain (ar_hash, region->outer); 2435 next = collect_one_action_chain (ar_hash, region->outer);
2435 2436
2436 /* If there is no next action, terminate the chain. */ 2437 /* If there is no next action, terminate the chain. */
2437 if (next == -1) 2438 if (next == -1)
2438 next = 0; 2439 next = 0;
2439 /* If all outer actions are cleanups or must_not_throw, 2440 /* If all outer actions are cleanups or must_not_throw,
2440 we'll have no action record for it, since we had wanted 2441 we'll have no action record for it, since we had wanted
2441 to encode these states in the call-site record directly. 2442 to encode these states in the call-site record directly.
2442 Add a cleanup action to the chain to catch these. */ 2443 Add a cleanup action to the chain to catch these. */
2443 else if (next <= 0) 2444 else if (next <= 0)
2444 next = add_action_record (ar_hash, 0, 0); 2445 next = add_action_record (ar_hash, 0, 0);
2445 2446
2446 return add_action_record (ar_hash, region->u.allowed.filter, next); 2447 return add_action_record (ar_hash, region->u.allowed.filter, next);
2447 2448
2448 case ERT_MUST_NOT_THROW: 2449 case ERT_MUST_NOT_THROW:
2449 /* A must-not-throw region with no inner handlers or cleanups 2450 /* A must-not-throw region with no inner handlers or cleanups
2450 requires no call-site entry. Note that this differs from 2451 requires no call-site entry. Note that this differs from
2451 the no handler or cleanup case in that we do require an lsda 2452 the no handler or cleanup case in that we do require an lsda
2452 to be generated. Return a magic -2 value to record this. */ 2453 to be generated. Return a magic -2 value to record this. */
2453 return -2; 2454 return -2;
2454 } 2455 }
2455 2456
2456 gcc_unreachable (); 2457 gcc_unreachable ();
2457} 2458}
2458 2459
2459static int 2460static int
2460add_call_site (rtx landing_pad, int action, int section) 2461add_call_site (rtx landing_pad, int action, int section)
2461{ 2462{
2462 call_site_record record; 2463 call_site_record record;
2463 2464
2464 record = ggc_alloc<call_site_record_d> (); 2465 record = ggc_alloc<call_site_record_d> ();
2465 record->landing_pad = landing_pad; 2466 record->landing_pad = landing_pad;
2466 record->action = action; 2467 record->action = action;
2467 2468
2468 vec_safe_push (crtl->eh.call_site_record_v[section], record); 2469 vec_safe_push (crtl->eh.call_site_record_v[section], record);
2469 2470
2470 return call_site_base + crtl->eh.call_site_record_v[section]->length () - 1; 2471 return call_site_base + crtl->eh.call_site_record_v[section]->length () - 1;
2471} 2472}
2472 2473
2473static rtx_note * 2474static rtx_note *
2474emit_note_eh_region_end (rtx_insn *insn) 2475emit_note_eh_region_end (rtx_insn *insn)
2475{ 2476{
2476 rtx_insn *next = NEXT_INSN (insn); 2477 rtx_insn *next = NEXT_INSN (insn);
2477 2478
2478 /* Make sure we do not split a call and its corresponding 2479 /* Make sure we do not split a call and its corresponding
2479 CALL_ARG_LOCATION note. */ 2480 CALL_ARG_LOCATION note. */
2480 if (next && NOTE_P (next) 2481 if (next && NOTE_P (next)
2481 && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION) 2482 && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
2482 insn = next; 2483 insn = next;
2483 2484
2484 return emit_note_after (NOTE_INSN_EH_REGION_END, insn); 2485 return emit_note_after (NOTE_INSN_EH_REGION_END, insn);
2485} 2486}
2486 2487
2487/* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes. 2488/* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
2488 The new note numbers will not refer to region numbers, but 2489 The new note numbers will not refer to region numbers, but
2489 instead to call site entries. */ 2490 instead to call site entries. */
2490 2491
2491static unsigned int 2492static unsigned int
2492convert_to_eh_region_ranges (void) 2493convert_to_eh_region_ranges (void)
2493{ 2494{
2494 rtx insn; 2495 rtx insn;
2495 rtx_insn *iter; 2496 rtx_insn *iter;
2496 rtx_note *note; 2497 rtx_note *note;
2497 action_hash_type ar_hash (31); 2498 action_hash_type ar_hash (31);
2498 int last_action = -3; 2499 int last_action = -3;
2499 rtx_insn *last_action_insn = NULL; 2500 rtx_insn *last_action_insn = NULL;
2500 rtx last_landing_pad = NULL_RTX; 2501 rtx last_landing_pad = NULL_RTX;
2501 rtx_insn *first_no_action_insn = NULL; 2502 rtx_insn *first_no_action_insn = NULL;
2502 int call_site = 0; 2503 int call_site = 0;
2503 int cur_sec = 0; 2504 int cur_sec = 0;
2504 rtx section_switch_note = NULL_RTX; 2505 rtx section_switch_note = NULL_RTX;
2505 rtx_insn *first_no_action_insn_before_switch = NULL; 2506 rtx_insn *first_no_action_insn_before_switch = NULL;
2506 rtx_insn *last_no_action_insn_before_switch = NULL; 2507 rtx_insn *last_no_action_insn_before_switch = NULL;
2507 int saved_call_site_base = call_site_base; 2508 int saved_call_site_base = call_site_base;
2508 2509
2509 vec_alloc (crtl->eh.action_record_data, 64); 2510 vec_alloc (crtl->eh.action_record_data, 64);
2510 2511
2511 for (iter = get_insns (); iter ; iter = NEXT_INSN (iter)) 2512 for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
2512 if (INSN_P (iter)) 2513 if (INSN_P (iter))
2513 { 2514 {
2514 eh_landing_pad lp; 2515 eh_landing_pad lp;
2515 eh_region region; 2516 eh_region region;
2516 bool nothrow; 2517 bool nothrow;
2517 int this_action; 2518 int this_action;
2518 rtx this_landing_pad; 2519 rtx this_landing_pad;
2519 2520
2520 insn = iter; 2521 insn = iter;
2521 if (NONJUMP_INSN_P (insn) 2522 if (NONJUMP_INSN_P (insn)
2522 && GET_CODE (PATTERN (insn)) == SEQUENCE) 2523 && GET_CODE (PATTERN (insn)) == SEQUENCE)
2523 insn = XVECEXP (PATTERN (insn), 0, 0); 2524 insn = XVECEXP (PATTERN (insn), 0, 0);
2524 2525
2525 nothrow = get_eh_region_and_lp_from_rtx (insn, &region, &lp); 2526 nothrow = get_eh_region_and_lp_from_rtx (insn, &region, &lp);
2526 if (nothrow) 2527 if (nothrow)
2527 continue; 2528 continue;
2528 if (region) 2529 if (region)
2529 this_action = collect_one_action_chain (&ar_hash, region); 2530 this_action = collect_one_action_chain (&ar_hash, region);
2530 else 2531 else
2531 this_action = -1; 2532 this_action = -1;
2532 2533
2533 /* Existence of catch handlers, or must-not-throw regions 2534 /* Existence of catch handlers, or must-not-throw regions
2534 implies that an lsda is needed (even if empty). */ 2535 implies that an lsda is needed (even if empty). */
2535 if (this_action != -1) 2536 if (this_action != -1)
2536 crtl->uses_eh_lsda = 1; 2537 crtl->uses_eh_lsda = 1;
2537 2538
2538 /* Delay creation of region notes for no-action regions 2539 /* Delay creation of region notes for no-action regions
2539 until we're sure that an lsda will be required. */ 2540 until we're sure that an lsda will be required. */
2540 else if (last_action == -3) 2541 else if (last_action == -3)
2541 { 2542 {
2542 first_no_action_insn = iter; 2543 first_no_action_insn = iter;
2543 last_action = -1; 2544 last_action = -1;
2544 } 2545 }
2545 2546
2546 if (this_action >= 0) 2547 if (this_action >= 0)
2547 this_landing_pad = lp->landing_pad; 2548 this_landing_pad = lp->landing_pad;
2548 else 2549 else
2549 this_landing_pad = NULL_RTX; 2550 this_landing_pad = NULL_RTX;
2550 2551
2551 /* Differing actions or landing pads implies a change in call-site 2552 /* Differing actions or landing pads implies a change in call-site
2552 info, which implies some EH_REGION note should be emitted. */ 2553 info, which implies some EH_REGION note should be emitted. */
2553 if (last_action != this_action 2554 if (last_action != this_action
2554 || last_landing_pad != this_landing_pad) 2555 || last_landing_pad != this_landing_pad)
2555 { 2556 {
2556 /* If there is a queued no-action region in the other section 2557 /* If there is a queued no-action region in the other section
2557 with hot/cold partitioning, emit it now. */ 2558 with hot/cold partitioning, emit it now. */
2558 if (first_no_action_insn_before_switch) 2559 if (first_no_action_insn_before_switch)
2559 { 2560 {
2560 gcc_assert (this_action != -1 2561 gcc_assert (this_action != -1
2561 && last_action == (first_no_action_insn 2562 && last_action == (first_no_action_insn
2562 ? -1 : -3)); 2563 ? -1 : -3));
2563 call_site = add_call_site (NULL_RTX, 0, 0); 2564 call_site = add_call_site (NULL_RTX, 0, 0);
2564 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, 2565 note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
2565 first_no_action_insn_before_switch); 2566 first_no_action_insn_before_switch);
2566 NOTE_EH_HANDLER (note) = call_site; 2567 NOTE_EH_HANDLER (note) = call_site;
2567 note 2568 note
2568 = emit_note_eh_region_end (last_no_action_insn_before_switch); 2569 = emit_note_eh_region_end (last_no_action_insn_before_switch);
2569 NOTE_EH_HANDLER (note) = call_site; 2570 NOTE_EH_HANDLER (note) = call_site;
2570 gcc_assert (last_action != -3 2571 gcc_assert (last_action != -3
2571 || (last_action_insn 2572 || (last_action_insn
2572 == last_no_action_insn_before_switch)); 2573 == last_no_action_insn_before_switch));
2573 first_no_action_insn_before_switch = NULL; 2574 first_no_action_insn_before_switch = NULL;
2574 last_no_action_insn_before_switch = NULL; 2575 last_no_action_insn_before_switch = NULL;
2575 call_site_base++; 2576 call_site_base++;
2576 } 2577 }
2577 /* If we'd not seen a previous action (-3) or the previous 2578 /* If we'd not seen a previous action (-3) or the previous
2578 action was must-not-throw (-2), then we do not need an 2579 action was must-not-throw (-2), then we do not need an
2579 end note. */ 2580 end note. */
2580 if (last_action >= -1) 2581 if (last_action >= -1)
2581 { 2582 {
2582 /* If we delayed the creation of the begin, do it now. */ 2583 /* If we delayed the creation of the begin, do it now. */
2583 if (first_no_action_insn) 2584 if (first_no_action_insn)
2584 { 2585 {
2585 call_site = add_call_site (NULL_RTX, 0, cur_sec); 2586 call_site = add_call_site (NULL_RTX, 0, cur_sec);
2586 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, 2587 note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
2587 first_no_action_insn); 2588 first_no_action_insn);
2588 NOTE_EH_HANDLER (note) = call_site; 2589 NOTE_EH_HANDLER (note) = call_site;
2589 first_no_action_insn = NULL; 2590 first_no_action_insn = NULL;
2590 } 2591 }
2591 2592
2592 note = emit_note_eh_region_end (last_action_insn); 2593 note = emit_note_eh_region_end (last_action_insn);
2593 NOTE_EH_HANDLER (note) = call_site; 2594 NOTE_EH_HANDLER (note) = call_site;
2594 } 2595 }
2595 2596
2596 /* If the new action is must-not-throw, then no region notes 2597 /* If the new action is must-not-throw, then no region notes
2597 are created. */ 2598 are created. */
2598 if (this_action >= -1) 2599 if (this_action >= -1)
2599 { 2600 {
2600 call_site = add_call_site (this_landing_pad, 2601 call_site = add_call_site (this_landing_pad,
2601 this_action < 0 ? 0 : this_action, 2602 this_action < 0 ? 0 : this_action,
2602 cur_sec); 2603 cur_sec);
2603 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter); 2604 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
2604 NOTE_EH_HANDLER (note) = call_site; 2605 NOTE_EH_HANDLER (note) = call_site;
2605 } 2606 }
2606 2607
2607 last_action = this_action; 2608 last_action = this_action;
2608 last_landing_pad = this_landing_pad; 2609 last_landing_pad = this_landing_pad;
2609 } 2610 }
2610 last_action_insn = iter; 2611 last_action_insn = iter;
2611 } 2612 }
2612 else if (NOTE_P (iter) 2613 else if (NOTE_P (iter)
2613 && NOTE_KIND (iter) == NOTE_INSN_SWITCH_TEXT_SECTIONS) 2614 && NOTE_KIND (iter) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
2614 { 2615 {
2615 gcc_assert (section_switch_note == NULL_RTX); 2616 gcc_assert (section_switch_note == NULL_RTX);
2616 gcc_assert (flag_reorder_blocks_and_partition); 2617 gcc_assert (flag_reorder_blocks_and_partition);
2617 section_switch_note = iter; 2618 section_switch_note = iter;
2618 if (first_no_action_insn) 2619 if (first_no_action_insn)
2619 { 2620 {
2620 first_no_action_insn_before_switch = first_no_action_insn; 2621 first_no_action_insn_before_switch = first_no_action_insn;
2621 last_no_action_insn_before_switch = last_action_insn; 2622 last_no_action_insn_before_switch = last_action_insn;
2622 first_no_action_insn = NULL; 2623 first_no_action_insn = NULL;
2623 gcc_assert (last_action == -1); 2624 gcc_assert (last_action == -1);
2624 last_action = -3; 2625 last_action = -3;
2625 } 2626 }
2626 /* Force closing of current EH region before section switch and 2627 /* Force closing of current EH region before section switch and
2627 opening a new one afterwards. */ 2628 opening a new one afterwards. */
2628 else if (last_action != -3) 2629 else if (last_action != -3)
2629 last_landing_pad = pc_rtx; 2630 last_landing_pad = pc_rtx;
2630 if (crtl->eh.call_site_record_v[cur_sec]) 2631 if (crtl->eh.call_site_record_v[cur_sec])
2631 call_site_base += crtl->eh.call_site_record_v[cur_sec]->length (); 2632 call_site_base += crtl->eh.call_site_record_v[cur_sec]->length ();
2632 cur_sec++; 2633 cur_sec++;
2633 gcc_assert (crtl->eh.call_site_record_v[cur_sec] == NULL); 2634 gcc_assert (crtl->eh.call_site_record_v[cur_sec] == NULL);
2634 vec_alloc (crtl->eh.call_site_record_v[cur_sec], 10); 2635 vec_alloc (crtl->eh.call_site_record_v[cur_sec], 10);
2635 } 2636 }
2636 2637
2637 if (last_action >= -1 && ! first_no_action_insn) 2638 if (last_action >= -1 && ! first_no_action_insn)
2638 { 2639 {
2639 note = emit_note_eh_region_end (last_action_insn); 2640 note = emit_note_eh_region_end (last_action_insn);
2640 NOTE_EH_HANDLER (note) = call_site; 2641 NOTE_EH_HANDLER (note) = call_site;
2641 } 2642 }
2642 2643
2643 call_site_base = saved_call_site_base; 2644 call_site_base = saved_call_site_base;
2644 2645
2645 return 0; 2646 return 0;
2646} 2647}
2647 2648
2648namespace { 2649namespace {
2649 2650
2650const pass_data pass_data_convert_to_eh_region_ranges = 2651const pass_data pass_data_convert_to_eh_region_ranges =
2651{ 2652{
2652 RTL_PASS, /* type */ 2653 RTL_PASS, /* type */
2653 "eh_ranges", /* name */ 2654 "eh_ranges", /* name */
2654 OPTGROUP_NONE, /* optinfo_flags */ 2655 OPTGROUP_NONE, /* optinfo_flags */
2655 TV_NONE, /* tv_id */ 2656 TV_NONE, /* tv_id */
2656 0, /* properties_required */ 2657 0, /* properties_required */
2657 0, /* properties_provided */ 2658 0, /* properties_provided */
2658 0, /* properties_destroyed */ 2659 0, /* properties_destroyed */
2659 0, /* todo_flags_start */ 2660 0, /* todo_flags_start */
2660 0, /* todo_flags_finish */ 2661 0, /* todo_flags_finish */
2661}; 2662};
2662 2663
2663class pass_convert_to_eh_region_ranges : public rtl_opt_pass 2664class pass_convert_to_eh_region_ranges : public rtl_opt_pass
2664{ 2665{
2665public: 2666public:
2666 pass_convert_to_eh_region_ranges (gcc::context *ctxt) 2667 pass_convert_to_eh_region_ranges (gcc::context *ctxt)
2667 : rtl_opt_pass (pass_data_convert_to_eh_region_ranges, ctxt) 2668 : rtl_opt_pass (pass_data_convert_to_eh_region_ranges, ctxt)
2668 {} 2669 {}
2669 2670
2670 /* opt_pass methods: */ 2671 /* opt_pass methods: */
2671 virtual bool gate (function *); 2672 virtual bool gate (function *);
2672 virtual unsigned int execute (function *) 2673 virtual unsigned int execute (function *)
2673 { 2674 {
2674 return convert_to_eh_region_ranges (); 2675 return convert_to_eh_region_ranges ();
2675 } 2676 }
2676 2677
2677}; // class pass_convert_to_eh_region_ranges 2678}; // class pass_convert_to_eh_region_ranges
2678 2679
2679bool 2680bool
2680pass_convert_to_eh_region_ranges::gate (function *) 2681pass_convert_to_eh_region_ranges::gate (function *)
2681{ 2682{
2682 /* Nothing to do for SJLJ exceptions or if no regions created. */ 2683 /* Nothing to do for SJLJ exceptions or if no regions created. */
2683 if (cfun->eh->region_tree == NULL) 2684 if (cfun->eh->region_tree == NULL)
2684 return false; 2685 return false;
2685 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) 2686 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
2686 return false; 2687 return false;
2687 return true; 2688 return true;
2688} 2689}
2689 2690
2690} // anon namespace 2691} // anon namespace
2691 2692
2692rtl_opt_pass * 2693rtl_opt_pass *
2693make_pass_convert_to_eh_region_ranges (gcc::context *ctxt) 2694make_pass_convert_to_eh_region_ranges (gcc::context *ctxt)
2694{ 2695{
2695 return new pass_convert_to_eh_region_ranges (ctxt); 2696 return new pass_convert_to_eh_region_ranges (ctxt);
2696} 2697}
2697  2698
2698static void 2699static void
2699push_uleb128 (vec<uchar, va_gc> **data_area, unsigned int value) 2700push_uleb128 (vec<uchar, va_gc> **data_area, unsigned int value)
2700{ 2701{
2701 do 2702 do
2702 { 2703 {
2703 unsigned char byte = value & 0x7f; 2704 unsigned char byte = value & 0x7f;
2704 value >>= 7; 2705 value >>= 7;
2705 if (value) 2706 if (value)
2706 byte |= 0x80; 2707 byte |= 0x80;
2707 vec_safe_push (*data_area, byte); 2708 vec_safe_push (*data_area, byte);
2708 } 2709 }
2709 while (value); 2710 while (value);
2710} 2711}
2711 2712
2712static void 2713static void
2713push_sleb128 (vec<uchar, va_gc> **data_area, int value) 2714push_sleb128 (vec<uchar, va_gc> **data_area, int value)
2714{ 2715{
2715 unsigned char byte; 2716 unsigned char byte;
2716 int more; 2717 int more;
2717 2718
2718 do 2719 do
2719 { 2720 {
2720 byte = value & 0x7f; 2721 byte = value & 0x7f;
2721 value >>= 7; 2722 value >>= 7;
2722 more = ! ((value == 0 && (byte & 0x40) == 0) 2723 more = ! ((value == 0 && (byte & 0x40) == 0)
2723 || (value == -1 && (byte & 0x40) != 0)); 2724 || (value == -1 && (byte & 0x40) != 0));
2724 if (more) 2725 if (more)
2725 byte |= 0x80; 2726 byte |= 0x80;
2726 vec_safe_push (*data_area, byte); 2727 vec_safe_push (*data_area, byte);
2727 } 2728 }
2728 while (more); 2729 while (more);
2729} 2730}
2730 2731
2731  2732
2732#ifndef HAVE_AS_LEB128 2733#ifndef HAVE_AS_LEB128
2733static int 2734static int
2734dw2_size_of_call_site_table (int section) 2735dw2_size_of_call_site_table (int section)
2735{ 2736{
2736 int n = vec_safe_length (crtl->eh.call_site_record_v[section]); 2737 int n = vec_safe_length (crtl->eh.call_site_record_v[section]);
2737 int size = n * (4 + 4 + 4); 2738 int size = n * (4 + 4 + 4);
2738 int i; 2739 int i;
2739 2740
2740 for (i = 0; i < n; ++i) 2741 for (i = 0; i < n; ++i)
2741 { 2742 {
2742 struct call_site_record_d *cs = 2743 struct call_site_record_d *cs =
2743 (*crtl->eh.call_site_record_v[section])[i]; 2744 (*crtl->eh.call_site_record_v[section])[i];
2744 size += size_of_uleb128 (cs->action); 2745 size += size_of_uleb128 (cs->action);
2745 } 2746 }
2746 2747
2747 return size; 2748 return size;
2748} 2749}
2749 2750
2750static int 2751static int
2751sjlj_size_of_call_site_table (void) 2752sjlj_size_of_call_site_table (void)
2752{ 2753{
2753 int n = vec_safe_length (crtl->eh.call_site_record_v[0]); 2754 int n = vec_safe_length (crtl->eh.call_site_record_v[0]);
2754 int size = 0; 2755 int size = 0;
2755 int i; 2756 int i;
2756 2757
2757 for (i = 0; i < n; ++i) 2758 for (i = 0; i < n; ++i)
2758 { 2759 {
2759 struct call_site_record_d *cs = 2760 struct call_site_record_d *cs =
2760 (*crtl->eh.call_site_record_v[0])[i]; 2761 (*crtl->eh.call_site_record_v[0])[i];
2761 size += size_of_uleb128 (INTVAL (cs->landing_pad)); 2762 size += size_of_uleb128 (INTVAL (cs->landing_pad));
2762 size += size_of_uleb128 (cs->action); 2763 size += size_of_uleb128 (cs->action);
2763 } 2764 }
2764 2765
2765 return size; 2766 return size;
2766} 2767}
2767#endif 2768#endif
2768 2769
2769static void 2770static void
2770dw2_output_call_site_table (int cs_format, int section) 2771dw2_output_call_site_table (int cs_format, int section)
2771{ 2772{
2772 int n = vec_safe_length (crtl->eh.call_site_record_v[section]); 2773 int n = vec_safe_length (crtl->eh.call_site_record_v[section]);
2773 int i; 2774 int i;
2774 const char *begin; 2775 const char *begin;
2775 2776
2776 if (section == 0) 2777 if (section == 0)
2777 begin = current_function_func_begin_label; 2778 begin = current_function_func_begin_label;
2778 else if (first_function_block_is_cold) 2779 else if (first_function_block_is_cold)
2779 begin = crtl->subsections.hot_section_label; 2780 begin = crtl->subsections.hot_section_label;
2780 else 2781 else
2781 begin = crtl->subsections.cold_section_label; 2782 begin = crtl->subsections.cold_section_label;
2782 2783
2783 for (i = 0; i < n; ++i) 2784 for (i = 0; i < n; ++i)
2784 { 2785 {
2785 struct call_site_record_d *cs = (*crtl->eh.call_site_record_v[section])[i]; 2786 struct call_site_record_d *cs = (*crtl->eh.call_site_record_v[section])[i];
2786 char reg_start_lab[32]; 2787 char reg_start_lab[32];
2787 char reg_end_lab[32]; 2788 char reg_end_lab[32];
2788 char landing_pad_lab[32]; 2789 char landing_pad_lab[32];
2789 2790
2790 ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i); 2791 ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
2791 ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i); 2792 ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
2792 2793
2793 if (cs->landing_pad) 2794 if (cs->landing_pad)
2794 ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L", 2795 ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
2795 CODE_LABEL_NUMBER (cs->landing_pad)); 2796 CODE_LABEL_NUMBER (cs->landing_pad));
2796 2797
2797 /* ??? Perhaps use insn length scaling if the assembler supports 2798 /* ??? Perhaps use insn length scaling if the assembler supports
2798 generic arithmetic. */ 2799 generic arithmetic. */
2799 /* ??? Perhaps use attr_length to choose data1 or data2 instead of 2800 /* ??? Perhaps use attr_length to choose data1 or data2 instead of
2800 data4 if the function is small enough. */ 2801 data4 if the function is small enough. */
2801 if (cs_format == DW_EH_PE_uleb128) 2802 if (cs_format == DW_EH_PE_uleb128)
2802 { 2803 {
2803 dw2_asm_output_delta_uleb128 (reg_start_lab, begin, 2804 dw2_asm_output_delta_uleb128 (reg_start_lab, begin,
2804 "region %d start", i); 2805 "region %d start", i);
2805 dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab, 2806 dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
2806 "length"); 2807 "length");
2807 if (cs->landing_pad) 2808 if (cs->landing_pad)
2808 dw2_asm_output_delta_uleb128 (landing_pad_lab, begin, 2809 dw2_asm_output_delta_uleb128 (landing_pad_lab, begin,
2809 "landing pad"); 2810 "landing pad");
2810 else 2811 else
2811 dw2_asm_output_data_uleb128 (0, "landing pad"); 2812 dw2_asm_output_data_uleb128 (0, "landing pad");
2812 } 2813 }
2813 else 2814 else
2814 { 2815 {
2815 dw2_asm_output_delta (4, reg_start_lab, begin, 2816 dw2_asm_output_delta (4, reg_start_lab, begin,
2816 "region %d start", i); 2817 "region %d start", i);
2817 dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length"); 2818 dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
2818 if (cs->landing_pad) 2819 if (cs->landing_pad)
2819 dw2_asm_output_delta (4, landing_pad_lab, begin, 2820 dw2_asm_output_delta (4, landing_pad_lab, begin,
2820 "landing pad"); 2821 "landing pad");
2821 else 2822 else
2822 dw2_asm_output_data (4, 0, "landing pad"); 2823 dw2_asm_output_data (4, 0, "landing pad");
2823 } 2824 }
2824 dw2_asm_output_data_uleb128 (cs->action, "action"); 2825 dw2_asm_output_data_uleb128 (cs->action, "action");
2825 } 2826 }
2826 2827
2827 call_site_base += n; 2828 call_site_base += n;
2828} 2829}
2829 2830
2830static void 2831static void
2831sjlj_output_call_site_table (void) 2832sjlj_output_call_site_table (void)
2832{ 2833{
2833 int n = vec_safe_length (crtl->eh.call_site_record_v[0]); 2834 int n = vec_safe_length (crtl->eh.call_site_record_v[0]);
2834 int i; 2835 int i;
2835 2836
2836 for (i = 0; i < n; ++i) 2837 for (i = 0; i < n; ++i)
2837 { 2838 {
2838 struct call_site_record_d *cs = (*crtl->eh.call_site_record_v[0])[i]; 2839 struct call_site_record_d *cs = (*crtl->eh.call_site_record_v[0])[i];
2839 2840
2840 dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad), 2841 dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
2841 "region %d landing pad", i); 2842 "region %d landing pad", i);
2842 dw2_asm_output_data_uleb128 (cs->action, "action"); 2843 dw2_asm_output_data_uleb128 (cs->action, "action");
2843 } 2844 }
2844 2845
2845 call_site_base += n; 2846 call_site_base += n;
2846} 2847}
2847 2848
2848/* Switch to the section that should be used for exception tables. */ 2849/* Switch to the section that should be used for exception tables. */
2849 2850
2850static void 2851static void
2851switch_to_exception_section (const char * ARG_UNUSED (fnname)) 2852switch_to_exception_section (const char * ARG_UNUSED (fnname))
2852{ 2853{
2853 section *s; 2854 section *s;
2854 2855
2855 if (exception_section) 2856 if (exception_section)
2856 s = exception_section; 2857 s = exception_section;
2857 else 2858 else
2858 { 2859 {
2859 /* Compute the section and cache it into exception_section, 2860 /* Compute the section and cache it into exception_section,
2860 unless it depends on the function name. */ 2861 unless it depends on the function name. */
2861 if (targetm_common.have_named_sections) 2862 if (targetm_common.have_named_sections)
2862 { 2863 {
2863 int flags; 2864 int flags;
2864 2865
2865 if (EH_TABLES_CAN_BE_READ_ONLY) 2866 if (EH_TABLES_CAN_BE_READ_ONLY)
2866 { 2867 {
2867 int tt_format = 2868 int tt_format =
2868 ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1); 2869 ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
2869 flags = ((! flag_pic 2870 flags = ((! flag_pic
2870 || ((tt_format & 0x70) != DW_EH_PE_absptr 2871 || ((tt_format & 0x70) != DW_EH_PE_absptr
2871 && (tt_format & 0x70) != DW_EH_PE_aligned)) 2872 && (tt_format & 0x70) != DW_EH_PE_aligned))
2872 ? 0 : SECTION_WRITE); 2873 ? 0 : SECTION_WRITE);
2873 } 2874 }
2874 else 2875 else
2875 flags = SECTION_WRITE; 2876 flags = SECTION_WRITE;
2876 2877
2877#ifdef HAVE_LD_EH_GC_SECTIONS 2878#ifdef HAVE_LD_EH_GC_SECTIONS
2878 if (flag_function_sections 2879 if (flag_function_sections
2879 || (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)) 2880 || (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP))
2880 { 2881 {
2881 char *section_name = XNEWVEC (char, strlen (fnname) + 32); 2882 char *section_name = XNEWVEC (char, strlen (fnname) + 32);
2882 /* The EH table must match the code section, so only mark 2883 /* The EH table must match the code section, so only mark
2883 it linkonce if we have COMDAT groups to tie them together. */ 2884 it linkonce if we have COMDAT groups to tie them together. */
2884 if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP) 2885 if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)
2885 flags |= SECTION_LINKONCE; 2886 flags |= SECTION_LINKONCE;
2886 sprintf (section_name, ".gcc_except_table.%s", fnname); 2887 sprintf (section_name, ".gcc_except_table.%s", fnname);
2887 s = get_section (section_name, flags, current_function_decl); 2888 s = get_section (section_name, flags, current_function_decl);
2888 free (section_name); 2889 free (section_name);
2889 } 2890 }
2890 else 2891 else
2891#endif 2892#endif
2892 exception_section 2893 exception_section
2893 = s = get_section (".gcc_except_table", flags, NULL); 2894 = s = get_section (".gcc_except_table", flags, NULL);
2894 } 2895 }
2895 else 2896 else
2896 exception_section 2897 exception_section
2897 = s = flag_pic ? data_section : readonly_data_section; 2898 = s = flag_pic ? data_section : readonly_data_section;
2898 } 2899 }
2899 2900
2900 switch_to_section (s); 2901 switch_to_section (s);
2901} 2902}
2902 2903
2903 2904
2904/* Output a reference from an exception table to the type_info object TYPE. 2905/* Output a reference from an exception table to the type_info object TYPE.
2905 TT_FORMAT and TT_FORMAT_SIZE describe the DWARF encoding method used for 2906 TT_FORMAT and TT_FORMAT_SIZE describe the DWARF encoding method used for
2906 the value. */ 2907 the value. */
2907 2908
2908static void 2909static void
2909output_ttype (tree type, int tt_format, int tt_format_size) 2910output_ttype (tree type, int tt_format, int tt_format_size)
2910{ 2911{
2911 rtx value; 2912 rtx value;
2912 bool is_public = true; 2913 bool is_public = true;
2913 2914
2914 if (type == NULL_TREE) 2915 if (type == NULL_TREE)
2915 value = const0_rtx; 2916 value = const0_rtx;
2916 else 2917 else
2917 { 2918 {
2918 /* FIXME lto. pass_ipa_free_lang_data changes all types to 2919 /* FIXME lto. pass_ipa_free_lang_data changes all types to
2919 runtime types so TYPE should already be a runtime type 2920 runtime types so TYPE should already be a runtime type
2920 reference. When pass_ipa_free_lang data is made a default 2921 reference. When pass_ipa_free_lang data is made a default
2921 pass, we can then remove the call to lookup_type_for_runtime 2922 pass, we can then remove the call to lookup_type_for_runtime
2922 below. */ 2923 below. */
2923 if (TYPE_P (type)) 2924 if (TYPE_P (type))
2924 type = lookup_type_for_runtime (type); 2925 type = lookup_type_for_runtime (type);
2925 2926
2926 value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER); 2927 value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
2927 2928
2928 /* Let cgraph know that the rtti decl is used. Not all of the 2929 /* Let cgraph know that the rtti decl is used. Not all of the
2929 paths below go through assemble_integer, which would take 2930 paths below go through assemble_integer, which would take
2930 care of this for us. */ 2931 care of this for us. */
2931 STRIP_NOPS (type); 2932 STRIP_NOPS (type);
2932 if (TREE_CODE (type) == ADDR_EXPR) 2933 if (TREE_CODE (type) == ADDR_EXPR)
2933 { 2934 {
2934 type = TREE_OPERAND (type, 0); 2935 type = TREE_OPERAND (type, 0);
2935 if (TREE_CODE (type) == VAR_DECL) 2936 if (TREE_CODE (type) == VAR_DECL)
2936 is_public = TREE_PUBLIC (type); 2937 is_public = TREE_PUBLIC (type);
2937 } 2938 }
2938 else 2939 else
2939 gcc_assert (TREE_CODE (type) == INTEGER_CST); 2940 gcc_assert (TREE_CODE (type) == INTEGER_CST);
2940 } 2941 }
2941 2942
2942 /* Allow the target to override the type table entry format. */ 2943 /* Allow the target to override the type table entry format. */
2943 if (targetm.asm_out.ttype (value)) 2944 if (targetm.asm_out.ttype (value))
2944 return; 2945 return;
2945 2946
2946 if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned) 2947 if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
2947 assemble_integer (value, tt_format_size, 2948 assemble_integer (value, tt_format_size,
2948 tt_format_size * BITS_PER_UNIT, 1); 2949 tt_format_size * BITS_PER_UNIT, 1);
2949 else 2950 else
2950 dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL); 2951 dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL);
2951} 2952}
2952 2953
2953static void 2954static void
2954output_one_function_exception_table (int section) 2955output_one_function_exception_table (int section)
2955{ 2956{
2956 int tt_format, cs_format, lp_format, i; 2957 int tt_format, cs_format, lp_format, i;
2957#ifdef HAVE_AS_LEB128 2958#ifdef HAVE_AS_LEB128
2958 char ttype_label[32]; 2959 char ttype_label[32];
2959 char cs_after_size_label[32]; 2960 char cs_after_size_label[32];
2960 char cs_end_label[32]; 2961 char cs_end_label[32];
2961#else 2962#else
2962 int call_site_len; 2963 int call_site_len;
2963#endif 2964#endif
2964 int have_tt_data; 2965 int have_tt_data;
2965 int tt_format_size = 0; 2966 int tt_format_size = 0;
2966 2967
2967 have_tt_data = (vec_safe_length (cfun->eh->ttype_data) 2968 have_tt_data = (vec_safe_length (cfun->eh->ttype_data)
2968 || (targetm.arm_eabi_unwinder 2969 || (targetm.arm_eabi_unwinder
2969 ? vec_safe_length (cfun->eh->ehspec_data.arm_eabi) 2970 ? vec_safe_length (cfun->eh->ehspec_data.arm_eabi)
2970 : vec_safe_length (cfun->eh->ehspec_data.other))); 2971 : vec_safe_length (cfun->eh->ehspec_data.other)));
2971 2972
2972 /* Indicate the format of the @TType entries. */ 2973 /* Indicate the format of the @TType entries. */
2973 if (! have_tt_data) 2974 if (! have_tt_data)
2974 tt_format = DW_EH_PE_omit; 2975 tt_format = DW_EH_PE_omit;
2975 else 2976 else
2976 { 2977 {
2977 tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1); 2978 tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
2978#ifdef HAVE_AS_LEB128 2979#ifdef HAVE_AS_LEB128
2979 ASM_GENERATE_INTERNAL_LABEL (ttype_label, 2980 ASM_GENERATE_INTERNAL_LABEL (ttype_label,
2980 section ? "LLSDATTC" : "LLSDATT", 2981 section ? "LLSDATTC" : "LLSDATT",
2981 current_function_funcdef_no); 2982 current_function_funcdef_no);
2982#endif 2983#endif
2983 tt_format_size = size_of_encoded_value (tt_format); 2984 tt_format_size = size_of_encoded_value (tt_format);
2984 2985
2985 assemble_align (tt_format_size * BITS_PER_UNIT); 2986 assemble_align (tt_format_size * BITS_PER_UNIT);
2986 } 2987 }
2987 2988
2988 targetm.asm_out.internal_label (asm_out_file, section ? "LLSDAC" : "LLSDA", 2989 targetm.asm_out.internal_label (asm_out_file, section ? "LLSDAC" : "LLSDA",
2989 current_function_funcdef_no); 2990 current_function_funcdef_no);
2990 2991
2991 /* The LSDA header. */ 2992 /* The LSDA header. */
2992 2993
2993 /* Indicate the format of the landing pad start pointer. An omitted 2994 /* Indicate the format of the landing pad start pointer. An omitted
2994 field implies @LPStart == @Start. */ 2995 field implies @LPStart == @Start. */
2995 /* Currently we always put @LPStart == @Start. This field would 2996 /* Currently we always put @LPStart == @Start. This field would
2996 be most useful in moving the landing pads completely out of 2997 be most useful in moving the landing pads completely out of
2997 line to another section, but it could also be used to minimize 2998 line to another section, but it could also be used to minimize
2998 the size of uleb128 landing pad offsets. */ 2999 the size of uleb128 landing pad offsets. */
2999 lp_format = DW_EH_PE_omit; 3000 lp_format = DW_EH_PE_omit;
3000 dw2_asm_output_data (1, lp_format, "@LPStart format (%s)", 3001 dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
3001 eh_data_format_name (lp_format)); 3002 eh_data_format_name (lp_format));
3002 3003
3003 /* @LPStart pointer would go here. */ 3004 /* @LPStart pointer would go here. */
3004 3005
3005 dw2_asm_output_data (1, tt_format, "@TType format (%s)", 3006 dw2_asm_output_data (1, tt_format, "@TType format (%s)",
3006 eh_data_format_name (tt_format)); 3007 eh_data_format_name (tt_format));
3007 3008
3008#ifndef HAVE_AS_LEB128 3009#ifndef HAVE_AS_LEB128
3009 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) 3010 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
3010 call_site_len = sjlj_size_of_call_site_table (); 3011 call_site_len = sjlj_size_of_call_site_table ();
3011 else 3012 else
3012 call_site_len = dw2_size_of_call_site_table (section); 3013 call_site_len = dw2_size_of_call_site_table (section);
3013#endif 3014#endif
3014 3015
3015 /* A pc-relative 4-byte displacement to the @TType data. */ 3016 /* A pc-relative 4-byte displacement to the @TType data. */
3016 if (have_tt_data) 3017 if (have_tt_data)
3017 { 3018 {
3018#ifdef HAVE_AS_LEB128 3019#ifdef HAVE_AS_LEB128
3019 char ttype_after_disp_label[32]; 3020 char ttype_after_disp_label[32];
3020 ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, 3021 ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label,
3021 section ? "LLSDATTDC" : "LLSDATTD", 3022 section ? "LLSDATTDC" : "LLSDATTD",
3022 current_function_funcdef_no); 3023 current_function_funcdef_no);
3023 dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label, 3024 dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
3024 "@TType base offset"); 3025 "@TType base offset");
3025 ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label); 3026 ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
3026#else 3027#else
3027 /* Ug. Alignment queers things. */ 3028 /* Ug. Alignment queers things. */
3028 unsigned int before_disp, after_disp, last_disp, disp; 3029 unsigned int before_disp, after_disp, last_disp, disp;
3029 3030
3030 before_disp = 1 + 1; 3031 before_disp = 1 + 1;
3031 after_disp = (1 + size_of_uleb128 (call_site_len) 3032 after_disp = (1 + size_of_uleb128 (call_site_len)
3032 + call_site_len 3033 + call_site_len
3033 + vec_safe_length (crtl->eh.action_record_data) 3034 + vec_safe_length (crtl->eh.action_record_data)
3034 + (vec_safe_length (cfun->eh->ttype_data) 3035 + (vec_safe_length (cfun->eh->ttype_data)
3035 * tt_format_size)); 3036 * tt_format_size));
3036 3037
3037 disp = after_disp; 3038 disp = after_disp;
3038 do 3039 do
3039 { 3040 {
3040 unsigned int disp_size, pad; 3041 unsigned int disp_size, pad;
3041 3042
3042 last_disp = disp; 3043 last_disp = disp;
3043 disp_size = size_of_uleb128 (disp); 3044 disp_size = size_of_uleb128 (disp);
3044 pad = before_disp + disp_size + after_disp; 3045 pad = before_disp + disp_size + after_disp;
3045 if (pad % tt_format_size) 3046 if (pad % tt_format_size)
3046 pad = tt_format_size - (pad % tt_format_size); 3047 pad = tt_format_size - (pad % tt_format_size);
3047 else 3048 else
3048 pad = 0; 3049 pad = 0;
3049 disp = after_disp + pad; 3050 disp = after_disp + pad;
3050 } 3051 }
3051 while (disp != last_disp); 3052 while (disp != last_disp);
3052 3053
3053 dw2_asm_output_data_uleb128 (disp, "@TType base offset"); 3054 dw2_asm_output_data_uleb128 (disp, "@TType base offset");
3054#endif 3055#endif
3055 } 3056 }
3056 3057
3057 /* Indicate the format of the call-site offsets. */ 3058 /* Indicate the format of the call-site offsets. */
3058#ifdef HAVE_AS_LEB128 3059#ifdef HAVE_AS_LEB128
3059 cs_format = DW_EH_PE_uleb128; 3060 cs_format = DW_EH_PE_uleb128;
3060#else 3061#else
3061 cs_format = DW_EH_PE_udata4; 3062 cs_format = DW_EH_PE_udata4;
3062#endif 3063#endif
3063 dw2_asm_output_data (1, cs_format, "call-site format (%s)", 3064 dw2_asm_output_data (1, cs_format, "call-site format (%s)",
3064 eh_data_format_name (cs_format)); 3065 eh_data_format_name (cs_format));
3065 3066
3066#ifdef HAVE_AS_LEB128 3067#ifdef HAVE_AS_LEB128
3067 ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, 3068 ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label,
3068 section ? "LLSDACSBC" : "LLSDACSB", 3069 section ? "LLSDACSBC" : "LLSDACSB",
3069 current_function_funcdef_no); 3070 current_function_funcdef_no);
3070 ASM_GENERATE_INTERNAL_LABEL (cs_end_label, 3071 ASM_GENERATE_INTERNAL_LABEL (cs_end_label,
3071 section ? "LLSDACSEC" : "LLSDACSE", 3072 section ? "LLSDACSEC" : "LLSDACSE",
3072 current_function_funcdef_no); 3073 current_function_funcdef_no);
3073 dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label, 3074 dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
3074 "Call-site table length"); 3075 "Call-site table length");
3075 ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label); 3076 ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
3076 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) 3077 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
3077 sjlj_output_call_site_table (); 3078 sjlj_output_call_site_table ();
3078 else 3079 else
3079 dw2_output_call_site_table (cs_format, section); 3080 dw2_output_call_site_table (cs_format, section);
3080 ASM_OUTPUT_LABEL (asm_out_file, cs_end_label); 3081 ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
3081#else 3082#else
3082 dw2_asm_output_data_uleb128 (call_site_len, "Call-site table length"); 3083 dw2_asm_output_data_uleb128 (call_site_len, "Call-site table length");
3083 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) 3084 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
3084 sjlj_output_call_site_table (); 3085 sjlj_output_call_site_table ();
3085 else 3086 else
3086 dw2_output_call_site_table (cs_format, section); 3087 dw2_output_call_site_table (cs_format, section);
3087#endif 3088#endif
3088 3089
3089 /* ??? Decode and interpret the data for flag_debug_asm. */ 3090 /* ??? Decode and interpret the data for flag_debug_asm. */
3090 { 3091 {
3091 uchar uc; 3092 uchar uc;
3092 FOR_EACH_VEC_ELT (*crtl->eh.action_record_data, i, uc) 3093 FOR_EACH_VEC_ELT (*crtl->eh.action_record_data, i, uc)
3093 dw2_asm_output_data (1, uc, i ? NULL : "Action record table"); 3094 dw2_asm_output_data (1, uc, i ? NULL : "Action record table");
3094 } 3095 }
3095 3096
3096 if (have_tt_data) 3097 if (have_tt_data)
3097 assemble_align (tt_format_size * BITS_PER_UNIT); 3098 assemble_align (tt_format_size * BITS_PER_UNIT);
3098 3099
3099 i = vec_safe_length (cfun->eh->ttype_data); 3100 i = vec_safe_length (cfun->eh->ttype_data);
3100 while (i-- > 0) 3101 while (i-- > 0)
3101 { 3102 {
3102 tree type = (*cfun->eh->ttype_data)[i]; 3103 tree type = (*cfun->eh->ttype_data)[i];
3103 output_ttype (type, tt_format, tt_format_size); 3104 output_ttype (type, tt_format, tt_format_size);
3104 } 3105 }
3105 3106
3106#ifdef HAVE_AS_LEB128 3107#ifdef HAVE_AS_LEB128
3107 if (have_tt_data) 3108 if (have_tt_data)
3108 ASM_OUTPUT_LABEL (asm_out_file, ttype_label); 3109 ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
3109#endif 3110#endif
3110 3111
3111 /* ??? Decode and interpret the data for flag_debug_asm. */ 3112 /* ??? Decode and interpret the data for flag_debug_asm. */
3112 if (targetm.arm_eabi_unwinder) 3113 if (targetm.arm_eabi_unwinder)
3113 { 3114 {
3114 tree type; 3115 tree type;
3115 for (i = 0; 3116 for (i = 0;
3116 vec_safe_iterate (cfun->eh->ehspec_data.arm_eabi, i, &type); ++i) 3117 vec_safe_iterate (cfun->eh->ehspec_data.arm_eabi, i, &type); ++i)
3117 output_ttype (type, tt_format, tt_format_size); 3118 output_ttype (type, tt_format, tt_format_size);
3118 } 3119 }
3119 else 3120 else
3120 { 3121 {
3121 uchar uc; 3122 uchar uc;
3122 for (i = 0; 3123 for (i = 0;
3123 vec_safe_iterate (cfun->eh->ehspec_data.other, i, &uc); ++i) 3124 vec_safe_iterate (cfun->eh->ehspec_data.other, i, &uc); ++i)
3124 dw2_asm_output_data (1, uc, 3125 dw2_asm_output_data (1, uc,
3125 i ? NULL : "Exception specification table"); 3126 i ? NULL : "Exception specification table");
3126 } 3127 }
3127} 3128}
3128 3129
3129void 3130void
3130output_function_exception_table (const char *fnname) 3131output_function_exception_table (const char *fnname)
3131{ 3132{
3132 rtx personality = get_personality_function (current_function_decl); 3133 rtx personality = get_personality_function (current_function_decl);
3133 3134
3134 /* Not all functions need anything. */ 3135 /* Not all functions need anything. */
3135 if (! crtl->uses_eh_lsda) 3136 if (! crtl->uses_eh_lsda)
3136 return; 3137 return;
3137 3138
3138 if (personality) 3139 if (personality)
3139 { 3140 {
3140 assemble_external_libcall (personality); 3141 assemble_external_libcall (personality);
3141 3142
3142 if (targetm.asm_out.emit_except_personality) 3143 if (targetm.asm_out.emit_except_personality)
3143 targetm.asm_out.emit_except_personality (personality); 3144 targetm.asm_out.emit_except_personality (personality);
3144 } 3145 }
3145 3146
3146 switch_to_exception_section (fnname); 3147 switch_to_exception_section (fnname);
3147 3148
3148 /* If the target wants a label to begin the table, emit it here. */ 3149 /* If the target wants a label to begin the table, emit it here. */
3149 targetm.asm_out.emit_except_table_label (asm_out_file); 3150 targetm.asm_out.emit_except_table_label (asm_out_file);
3150 3151
3151 output_one_function_exception_table (0); 3152 output_one_function_exception_table (0);
3152 if (crtl->eh.call_site_record_v[1]) 3153 if (crtl->eh.call_site_record_v[1])
3153 output_one_function_exception_table (1); 3154 output_one_function_exception_table (1);
3154 3155
3155 switch_to_section (current_function_section ()); 3156 switch_to_section (current_function_section ());
3156} 3157}
3157 3158
3158void 3159void
3159set_eh_throw_stmt_table (function *fun, hash_map<gimple, int> *table) 3160set_eh_throw_stmt_table (function *fun, hash_map<gimple, int> *table)
3160{ 3161{
3161 fun->eh->throw_stmt_table = table; 3162 fun->eh->throw_stmt_table = table;
3162} 3163}
3163 3164
3164hash_map<gimple, int> * 3165hash_map<gimple, int> *
3165get_eh_throw_stmt_table (struct function *fun) 3166get_eh_throw_stmt_table (struct function *fun)
3166{ 3167{
3167 return fun->eh->throw_stmt_table; 3168 return fun->eh->throw_stmt_table;
3168} 3169}
3169  3170
3170/* Determine if the function needs an EH personality function. */ 3171/* Determine if the function needs an EH personality function. */
3171 3172
3172enum eh_personality_kind 3173enum eh_personality_kind
3173function_needs_eh_personality (struct function *fn) 3174function_needs_eh_personality (struct function *fn)
3174{ 3175{
3175 enum eh_personality_kind kind = eh_personality_none; 3176 enum eh_personality_kind kind = eh_personality_none;
3176 eh_region i; 3177 eh_region i;
3177 3178
3178 FOR_ALL_EH_REGION_FN (i, fn) 3179 FOR_ALL_EH_REGION_FN (i, fn)
3179 { 3180 {
3180 switch (i->type) 3181 switch (i->type)
3181 { 3182 {
3182 case ERT_CLEANUP: 3183 case ERT_CLEANUP:
3183 /* Can do with any personality including the generic C one. */ 3184 /* Can do with any personality including the generic C one. */
3184 kind = eh_personality_any; 3185 kind = eh_personality_any;
3185 break; 3186 break;
3186 3187
3187 case ERT_TRY: 3188 case ERT_TRY:
3188 case ERT_ALLOWED_EXCEPTIONS: 3189 case ERT_ALLOWED_EXCEPTIONS:
3189 /* Always needs a EH personality function. The generic C 3190 /* Always needs a EH personality function. The generic C
3190 personality doesn't handle these even for empty type lists. */ 3191 personality doesn't handle these even for empty type lists. */
3191 return eh_personality_lang; 3192 return eh_personality_lang;
3192 3193
3193 case ERT_MUST_NOT_THROW: 3194 case ERT_MUST_NOT_THROW:
3194 /* Always needs a EH personality function. The language may specify 3195 /* Always needs a EH personality function. The language may specify
3195 what abort routine that must be used, e.g. std::terminate. */ 3196 what abort routine that must be used, e.g. std::terminate. */
3196 return eh_personality_lang; 3197 return eh_personality_lang;
3197 } 3198 }
3198 } 3199 }
3199 3200
3200 return kind; 3201 return kind;
3201} 3202}
3202  3203
3203/* Dump EH information to OUT. */ 3204/* Dump EH information to OUT. */
3204 3205
3205void 3206void
3206dump_eh_tree (FILE * out, struct function *fun) 3207dump_eh_tree (FILE * out, struct function *fun)
3207{ 3208{
3208 eh_region i; 3209 eh_region i;
3209 int depth = 0; 3210 int depth = 0;
3210 static const char *const type_name[] = { 3211 static const char *const type_name[] = {
3211 "cleanup", "try", "allowed_exceptions", "must_not_throw" 3212 "cleanup", "try", "allowed_exceptions", "must_not_throw"
3212 }; 3213 };
3213 3214
3214 i = fun->eh->region_tree; 3215 i = fun->eh->region_tree;
3215 if (!i) 3216 if (!i)
3216 return; 3217 return;
3217 3218
3218 fprintf (out, "Eh tree:\n"); 3219 fprintf (out, "Eh tree:\n");
3219 while (1) 3220 while (1)
3220 { 3221 {
3221 fprintf (out, " %*s %i %s", depth * 2, "", 3222 fprintf (out, " %*s %i %s", depth * 2, "",
3222 i->index, type_name[(int) i->type]); 3223 i->index, type_name[(int) i->type]);
3223 3224
3224 if (i->landing_pads) 3225 if (i->landing_pads)
3225 { 3226 {
3226 eh_landing_pad lp; 3227 eh_landing_pad lp;
3227 3228
3228 fprintf (out, " land:"); 3229 fprintf (out, " land:");
3229 if (current_ir_type () == IR_GIMPLE) 3230 if (current_ir_type () == IR_GIMPLE)
3230 { 3231 {
3231 for (lp = i->landing_pads; lp ; lp = lp->next_lp) 3232 for (lp = i->landing_pads; lp ; lp = lp->next_lp)
3232 { 3233 {
3233 fprintf (out, "{%i,", lp->index); 3234 fprintf (out, "{%i,", lp->index);
3234 print_generic_expr (out, lp->post_landing_pad, 0); 3235 print_generic_expr (out, lp->post_landing_pad, 0);
3235 fputc ('}', out); 3236 fputc ('}', out);
3236 if (lp->next_lp) 3237 if (lp->next_lp)
3237 fputc (',', out); 3238 fputc (',', out);
3238 } 3239 }
3239 } 3240 }
3240 else 3241 else
3241 { 3242 {
3242 for (lp = i->landing_pads; lp ; lp = lp->next_lp) 3243 for (lp = i->landing_pads; lp ; lp = lp->next_lp)
3243 { 3244 {
3244 fprintf (out, "{%i,", lp->index); 3245 fprintf (out, "{%i,", lp->index);
3245 if (lp->landing_pad) 3246 if (lp->landing_pad)
3246 fprintf (out, "%i%s,", INSN_UID (lp->landing_pad), 3247 fprintf (out, "%i%s,", INSN_UID (lp->landing_pad),
3247 NOTE_P (lp->landing_pad) ? "(del)" : ""); 3248 NOTE_P (lp->landing_pad) ? "(del)" : "");
3248 else 3249 else
3249 fprintf (out, "(nil),"); 3250 fprintf (out, "(nil),");
3250 if (lp->post_landing_pad) 3251 if (lp->post_landing_pad)
3251 { 3252 {
3252 rtx lab = label_rtx (lp->post_landing_pad); 3253 rtx lab = label_rtx (lp->post_landing_pad);
3253 fprintf (out, "%i%s}", INSN_UID (lab), 3254 fprintf (out, "%i%s}", INSN_UID (lab),
3254 NOTE_P (lab) ? "(del)" : ""); 3255 NOTE_P (lab) ? "(del)" : "");
3255 } 3256 }
3256 else 3257 else
3257 fprintf (out, "(nil)}"); 3258 fprintf (out, "(nil)}");
3258 if (lp->next_lp) 3259 if (lp->next_lp)
3259 fputc (',', out); 3260 fputc (',', out);
3260 } 3261 }
3261 } 3262 }
3262 } 3263 }
3263 3264
3264 switch (i->type) 3265 switch (i->type)
3265 { 3266 {
3266 case ERT_CLEANUP: 3267 case ERT_CLEANUP:
3267 case ERT_MUST_NOT_THROW: 3268 case ERT_MUST_NOT_THROW:
3268 break; 3269 break;
3269 3270
3270 case ERT_TRY: 3271 case ERT_TRY:
3271 { 3272 {
3272 eh_catch c; 3273 eh_catch c;
3273 fprintf (out, " catch:"); 3274 fprintf (out, " catch:");
3274 for (c = i->u.eh_try.first_catch; c; c = c->next_catch) 3275 for (c = i->u.eh_try.first_catch; c; c = c->next_catch)
3275 { 3276 {
3276 fputc ('{', out); 3277 fputc ('{', out);
3277 if (c->label) 3278 if (c->label)
3278 { 3279 {
3279 fprintf (out, "lab:"); 3280 fprintf (out, "lab:");
3280 print_generic_expr (out, c->label, 0); 3281 print_generic_expr (out, c->label, 0);
3281 fputc (';', out); 3282 fputc (';', out);
3282 } 3283 }
3283 print_generic_expr (out, c->type_list, 0); 3284 print_generic_expr (out, c->type_list, 0);
3284 fputc ('}', out); 3285 fputc ('}', out);
3285 if (c->next_catch) 3286 if (c->next_catch)
3286 fputc (',', out); 3287 fputc (',', out);
3287 } 3288 }
3288 } 3289 }
3289 break; 3290 break;
3290 3291

cvs diff -r1.4 -r1.5 src/external/gpl3/gcc/dist/gcc/config/vax/elf.h (switch to unified diff)

--- src/external/gpl3/gcc/dist/gcc/config/vax/elf.h 2016/01/24 09:43:34 1.4
+++ src/external/gpl3/gcc/dist/gcc/config/vax/elf.h 2016/03/23 12:52:43 1.5
@@ -1,112 +1,98 @@ @@ -1,112 +1,98 @@
1/* Target definitions for GNU compiler for VAX using ELF 1/* Target definitions for GNU compiler for VAX using ELF
2 Copyright (C) 2002-2015 Free Software Foundation, Inc. 2 Copyright (C) 2002-2015 Free Software Foundation, Inc.
3 Contributed by Matt Thomas <matt@3am-software.com> 3 Contributed by Matt Thomas <matt@3am-software.com>
4 4
5This file is part of GCC. 5This file is part of GCC.
6 6
7GCC is free software; you can redistribute it and/or modify 7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by 8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option) 9the Free Software Foundation; either version 3, or (at your option)
10any later version. 10any later version.
11 11
12GCC is distributed in the hope that it will be useful, 12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of 13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details. 15GNU General Public License for more details.
16 16
17You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */ 19<http://www.gnu.org/licenses/>. */
20 20
21#undef TARGET_ELF 21#undef TARGET_ELF
22#define TARGET_ELF 1 22#define TARGET_ELF 1
23 23
24#undef REGISTER_PREFIX 24#undef REGISTER_PREFIX
25#undef REGISTER_NAMES 25#undef REGISTER_NAMES
26#define REGISTER_PREFIX "%" 26#define REGISTER_PREFIX "%"
27#define REGISTER_NAMES \ 27#define REGISTER_NAMES \
28 { "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \ 28 { "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \
29 "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", } 29 "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", }
30 30
31#undef SIZE_TYPE 31#undef SIZE_TYPE
32#define SIZE_TYPE "long unsigned int" 32#define SIZE_TYPE "long unsigned int"
33 33
34#undef PTRDIFF_TYPE 34#undef PTRDIFF_TYPE
35#define PTRDIFF_TYPE "long int" 35#define PTRDIFF_TYPE "long int"
36 36
37/* Profiling routine. */ 37/* Profiling routine. */
38#undef VAX_FUNCTION_PROFILER_NAME 38#undef VAX_FUNCTION_PROFILER_NAME
39#define VAX_FUNCTION_PROFILER_NAME "__mcount" 39#define VAX_FUNCTION_PROFILER_NAME "__mcount"
40 40
41/* Let's be re-entrant. */ 41/* Let's be re-entrant. */
42#undef PCC_STATIC_STRUCT_RETURN 42#undef PCC_STATIC_STRUCT_RETURN
43 43
44/* Before the prologue, the top of the frame is below the argument 44/* Before the prologue, the top of the frame is below the argument
45 count pushed by the CALLS and before the start of the saved registers. */ 45 count pushed by the CALLS and before the start of the saved registers. */
46#define INCOMING_FRAME_SP_OFFSET 0 46#define INCOMING_FRAME_SP_OFFSET 0
47 47
48/* Offset from the frame pointer register value to the top of the stack. */ 48/* We use R2-R3 (call-clobbered) registers for exceptions. */
49#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0 49#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + 2 : INVALID_REGNUM)
50 
51/* We use R2-R5 (call-clobbered) registers for exceptions. */ 
52#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 2 : INVALID_REGNUM) 
53 
54/* Place the top of the stack for the DWARF2 EH stackadj value. */ 
55#define EH_RETURN_STACKADJ_RTX \ 
56 gen_rtx_MEM (SImode, \ 
57 plus_constant (Pmode, \ 
58 gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),\ 
59 -4)) 
60 50
61/* Simple store the return handler into the call frame. */ 51/* Simple store the return handler into the call frame. */
62#define EH_RETURN_HANDLER_RTX \ 52#define EH_RETURN_HANDLER_RTX \
63 gen_rtx_MEM (Pmode, \ 53 gen_rtx_MEM (Pmode, \
64 plus_constant (Pmode, \ 54 plus_constant (Pmode, \
65 gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),\ 55 gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),\
66 16)) 56 16))
67 57
68 58
69/* Reserve the top of the stack for exception handler stackadj value. */ 
70#undef STARTING_FRAME_OFFSET 
71#define STARTING_FRAME_OFFSET -4 
72 
73/* The VAX wants no space between the case instruction and the jump table. */ 59/* The VAX wants no space between the case instruction and the jump table. */
74#undef ASM_OUTPUT_BEFORE_CASE_LABEL 60#undef ASM_OUTPUT_BEFORE_CASE_LABEL
75#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) 61#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE)
76 62
77#undef SUBTARGET_OVERRIDE_OPTIONS 63#undef SUBTARGET_OVERRIDE_OPTIONS
78#define SUBTARGET_OVERRIDE_OPTIONS \ 64#define SUBTARGET_OVERRIDE_OPTIONS \
79 do \ 65 do \
80 { \ 66 { \
81 /* Turn off function CSE if we're doing PIC. */ \ 67 /* Turn off function CSE if we're doing PIC. */ \
82 if (flag_pic) \ 68 if (flag_pic) \
83 flag_no_function_cse = 1; \ 69 flag_no_function_cse = 1; \
84 } \ 70 } \
85 while (0) 71 while (0)
86 72
87/* Don't allow *foo which foo is non-local */ 73/* Don't allow *foo which foo is non-local */
88#define NO_EXTERNAL_INDIRECT_ADDRESS 74#define NO_EXTERNAL_INDIRECT_ADDRESS
89 75
90#undef VAX_CC1_AND_CC1PLUS_SPEC 76#undef VAX_CC1_AND_CC1PLUS_SPEC
91#define VAX_CC1_AND_CC1PLUS_SPEC \ 77#define VAX_CC1_AND_CC1PLUS_SPEC \
92 "%{!fno-pic: \ 78 "%{!fno-pic: \
93 %{!fpic: \ 79 %{!fpic: \
94 %{!fPIC:-fPIC}}}" 80 %{!fPIC:-fPIC}}}"
95 81
96/* VAX ELF is always gas; override the generic VAX ASM_SPEC. */ 82/* VAX ELF is always gas; override the generic VAX ASM_SPEC. */
97 83
98#undef ASM_SPEC 84#undef ASM_SPEC
99#define ASM_SPEC "%{!fno-pic: %{!mno-asm-pic:-k}}" 85#define ASM_SPEC "%{!fno-pic: %{!mno-asm-pic:-k}}"
100 86
101/* We want PCREL dwarf output. */ 87/* We want PCREL dwarf output. */
102#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \ 88#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
103 ((GLOBAL ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) 89 ((GLOBAL ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4)
104 90
105/* Emit a PC-relative relocation. */ 91/* Emit a PC-relative relocation. */
106#define ASM_OUTPUT_DWARF_PCREL(FILE, SIZE, LABEL) \ 92#define ASM_OUTPUT_DWARF_PCREL(FILE, SIZE, LABEL) \
107 do { \ 93 do { \
108 fputs (integer_asm_op (SIZE, FALSE), FILE); \ 94 fputs (integer_asm_op (SIZE, FALSE), FILE); \
109 fprintf (FILE, "%%pcrel%d(", SIZE * 8); \ 95 fprintf (FILE, "%%pcrel%d(", SIZE * 8); \
110 assemble_name (FILE, LABEL); \ 96 assemble_name (FILE, LABEL); \
111 fprintf (FILE, "%+d)", SIZE); \ 97 fprintf (FILE, "%+d)", SIZE); \
112 } while (0) 98 } while (0)

cvs diff -r1.11 -r1.12 src/external/gpl3/gcc/dist/gcc/config/vax/vax.c (switch to unified diff)

--- src/external/gpl3/gcc/dist/gcc/config/vax/vax.c 2016/01/24 09:43:34 1.11
+++ src/external/gpl3/gcc/dist/gcc/config/vax/vax.c 2016/03/23 12:52:43 1.12
@@ -1,1197 +1,1198 @@ @@ -1,1197 +1,1198 @@
1/* Subroutines for insn-output.c for VAX. 1/* Subroutines for insn-output.c for VAX.
2 Copyright (C) 1987-2015 Free Software Foundation, Inc. 2 Copyright (C) 1987-2015 Free Software Foundation, Inc.
3 3
4This file is part of GCC. 4This file is part of GCC.
5 5
6GCC is free software; you can redistribute it and/or modify 6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by 7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option) 8the Free Software Foundation; either version 3, or (at your option)
9any later version. 9any later version.
10 10
11GCC is distributed in the hope that it will be useful, 11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of 12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details. 14GNU General Public License for more details.
15 15
16You should have received a copy of the GNU General Public License 16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */ 18<http://www.gnu.org/licenses/>. */
19 19
20#include "config.h" 20#include "config.h"
21#include "system.h" 21#include "system.h"
22#include "coretypes.h" 22#include "coretypes.h"
23#include "tm.h" 23#include "tm.h"
24#include "rtl.h" 24#include "rtl.h"
25#include "dominance.h" 25#include "dominance.h"
26#include "cfg.h" 26#include "cfg.h"
27#include "cfgrtl.h" 27#include "cfgrtl.h"
28#include "cfganal.h" 28#include "cfganal.h"
29#include "lcm.h" 29#include "lcm.h"
30#include "cfgbuild.h" 30#include "cfgbuild.h"
31#include "cfgcleanup.h" 31#include "cfgcleanup.h"
32#include "predict.h" 32#include "predict.h"
33#include "basic-block.h" 33#include "basic-block.h"
34#include "df.h" 34#include "df.h"
35#include "hash-set.h" 35#include "hash-set.h"
36#include "machmode.h" 36#include "machmode.h"
37#include "vec.h" 37#include "vec.h"
38#include "double-int.h" 38#include "double-int.h"
39#include "input.h" 39#include "input.h"
40#include "alias.h" 40#include "alias.h"
41#include "symtab.h" 41#include "symtab.h"
42#include "wide-int.h" 42#include "wide-int.h"
43#include "inchash.h" 43#include "inchash.h"
44#include "tree.h" 44#include "tree.h"
45#include "calls.h" 45#include "calls.h"
46#include "varasm.h" 46#include "varasm.h"
47#include "regs.h" 47#include "regs.h"
48#include "hard-reg-set.h" 48#include "hard-reg-set.h"
49#include "insn-config.h" 49#include "insn-config.h"
50#include "conditions.h" 50#include "conditions.h"
51#include "function.h" 51#include "function.h"
52#include "output.h" 52#include "output.h"
53#include "insn-attr.h" 53#include "insn-attr.h"
54#include "recog.h" 54#include "recog.h"
55#include "hashtab.h" 55#include "hashtab.h"
56#include "flags.h" 56#include "flags.h"
57#include "statistics.h" 57#include "statistics.h"
58#include "real.h" 58#include "real.h"
59#include "fixed-value.h" 59#include "fixed-value.h"
60#include "expmed.h" 60#include "expmed.h"
61#include "dojump.h" 61#include "dojump.h"
62#include "explow.h" 62#include "explow.h"
63#include "emit-rtl.h" 63#include "emit-rtl.h"
64#include "stmt.h" 64#include "stmt.h"
65#include "expr.h" 65#include "expr.h"
66#include "insn-codes.h" 66#include "insn-codes.h"
67#include "optabs.h" 67#include "optabs.h"
68#include "debug.h" 68#include "debug.h"
69#include "diagnostic-core.h" 69#include "diagnostic-core.h"
70#include "reload.h" 70#include "reload.h"
71#include "tm-preds.h" 71#include "tm-preds.h"
72#include "tm-constrs.h" 72#include "tm-constrs.h"
73#include "tm_p.h" 73#include "tm_p.h"
74#include "target.h" 74#include "target.h"
75#include "target-def.h" 75#include "target-def.h"
76#include "builtins.h" 76#include "builtins.h"
77 77
78static void vax_option_override (void); 78static void vax_option_override (void);
79static bool vax_legitimate_address_p (machine_mode, rtx, bool); 79static bool vax_legitimate_address_p (machine_mode, rtx, bool);
80static void vax_file_start (void); 80static void vax_file_start (void);
81static void vax_init_libfuncs (void); 81static void vax_init_libfuncs (void);
82static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, 82static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
83 HOST_WIDE_INT, tree); 83 HOST_WIDE_INT, tree);
84static int vax_address_cost_1 (rtx); 84static int vax_address_cost_1 (rtx);
85static int vax_address_cost (rtx, machine_mode, addr_space_t, bool); 85static int vax_address_cost (rtx, machine_mode, addr_space_t, bool);
86static bool vax_rtx_costs (rtx, int, int, int, int *, bool); 86static bool vax_rtx_costs (rtx, int, int, int, int *, bool);
87static rtx vax_function_arg (cumulative_args_t, machine_mode, 87static rtx vax_function_arg (cumulative_args_t, machine_mode,
88 const_tree, bool); 88 const_tree, bool);
89static void vax_function_arg_advance (cumulative_args_t, machine_mode, 89static void vax_function_arg_advance (cumulative_args_t, machine_mode,
90 const_tree, bool); 90 const_tree, bool);
91static rtx vax_struct_value_rtx (tree, int); 91static rtx vax_struct_value_rtx (tree, int);
92static rtx vax_builtin_setjmp_frame_value (void); 92static rtx vax_builtin_setjmp_frame_value (void);
93static void vax_asm_trampoline_template (FILE *); 93static void vax_asm_trampoline_template (FILE *);
94static void vax_trampoline_init (rtx, tree, rtx); 94static void vax_trampoline_init (rtx, tree, rtx);
95static int vax_return_pops_args (tree, tree, int); 95static int vax_return_pops_args (tree, tree, int);
96static bool vax_mode_dependent_address_p (const_rtx, addr_space_t); 96static bool vax_mode_dependent_address_p (const_rtx, addr_space_t);
97  97
98/* Initialize the GCC target structure. */ 98/* Initialize the GCC target structure. */
99#undef TARGET_ASM_ALIGNED_HI_OP 99#undef TARGET_ASM_ALIGNED_HI_OP
100#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" 100#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
101 101
102#undef TARGET_ASM_FILE_START 102#undef TARGET_ASM_FILE_START
103#define TARGET_ASM_FILE_START vax_file_start 103#define TARGET_ASM_FILE_START vax_file_start
104#undef TARGET_ASM_FILE_START_APP_OFF 104#undef TARGET_ASM_FILE_START_APP_OFF
105#define TARGET_ASM_FILE_START_APP_OFF true 105#define TARGET_ASM_FILE_START_APP_OFF true
106 106
107#undef TARGET_INIT_LIBFUNCS 107#undef TARGET_INIT_LIBFUNCS
108#define TARGET_INIT_LIBFUNCS vax_init_libfuncs 108#define TARGET_INIT_LIBFUNCS vax_init_libfuncs
109 109
110#undef TARGET_ASM_OUTPUT_MI_THUNK 110#undef TARGET_ASM_OUTPUT_MI_THUNK
111#define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk 111#define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
112#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK 112#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
113#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall 113#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
114 114
115#undef TARGET_RTX_COSTS 115#undef TARGET_RTX_COSTS
116#define TARGET_RTX_COSTS vax_rtx_costs 116#define TARGET_RTX_COSTS vax_rtx_costs
117#undef TARGET_ADDRESS_COST 117#undef TARGET_ADDRESS_COST
118#define TARGET_ADDRESS_COST vax_address_cost 118#define TARGET_ADDRESS_COST vax_address_cost
119 119
120#undef TARGET_PROMOTE_PROTOTYPES 120#undef TARGET_PROMOTE_PROTOTYPES
121#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true 121#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
122 122
123#undef TARGET_FUNCTION_ARG 123#undef TARGET_FUNCTION_ARG
124#define TARGET_FUNCTION_ARG vax_function_arg 124#define TARGET_FUNCTION_ARG vax_function_arg
125#undef TARGET_FUNCTION_ARG_ADVANCE 125#undef TARGET_FUNCTION_ARG_ADVANCE
126#define TARGET_FUNCTION_ARG_ADVANCE vax_function_arg_advance 126#define TARGET_FUNCTION_ARG_ADVANCE vax_function_arg_advance
127 127
128#undef TARGET_STRUCT_VALUE_RTX 128#undef TARGET_STRUCT_VALUE_RTX
129#define TARGET_STRUCT_VALUE_RTX vax_struct_value_rtx 129#define TARGET_STRUCT_VALUE_RTX vax_struct_value_rtx
130 130
131#undef TARGET_BUILTIN_SETJMP_FRAME_VALUE 131#undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
132#define TARGET_BUILTIN_SETJMP_FRAME_VALUE vax_builtin_setjmp_frame_value 132#define TARGET_BUILTIN_SETJMP_FRAME_VALUE vax_builtin_setjmp_frame_value
133 133
134#undef TARGET_LEGITIMATE_ADDRESS_P 134#undef TARGET_LEGITIMATE_ADDRESS_P
135#define TARGET_LEGITIMATE_ADDRESS_P vax_legitimate_address_p 135#define TARGET_LEGITIMATE_ADDRESS_P vax_legitimate_address_p
136#undef TARGET_MODE_DEPENDENT_ADDRESS_P 136#undef TARGET_MODE_DEPENDENT_ADDRESS_P
137#define TARGET_MODE_DEPENDENT_ADDRESS_P vax_mode_dependent_address_p 137#define TARGET_MODE_DEPENDENT_ADDRESS_P vax_mode_dependent_address_p
138 138
139#undef TARGET_FRAME_POINTER_REQUIRED 139#undef TARGET_FRAME_POINTER_REQUIRED
140#define TARGET_FRAME_POINTER_REQUIRED hook_bool_void_true 140#define TARGET_FRAME_POINTER_REQUIRED hook_bool_void_true
141 141
142#undef TARGET_ASM_TRAMPOLINE_TEMPLATE 142#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
143#define TARGET_ASM_TRAMPOLINE_TEMPLATE vax_asm_trampoline_template 143#define TARGET_ASM_TRAMPOLINE_TEMPLATE vax_asm_trampoline_template
144#undef TARGET_TRAMPOLINE_INIT 144#undef TARGET_TRAMPOLINE_INIT
145#define TARGET_TRAMPOLINE_INIT vax_trampoline_init 145#define TARGET_TRAMPOLINE_INIT vax_trampoline_init
146#undef TARGET_RETURN_POPS_ARGS 146#undef TARGET_RETURN_POPS_ARGS
147#define TARGET_RETURN_POPS_ARGS vax_return_pops_args 147#define TARGET_RETURN_POPS_ARGS vax_return_pops_args
148 148
149#undef TARGET_OPTION_OVERRIDE 149#undef TARGET_OPTION_OVERRIDE
150#define TARGET_OPTION_OVERRIDE vax_option_override 150#define TARGET_OPTION_OVERRIDE vax_option_override
151 151
152struct gcc_target targetm = TARGET_INITIALIZER; 152struct gcc_target targetm = TARGET_INITIALIZER;
153  153
154/* Set global variables as needed for the options enabled. */ 154/* Set global variables as needed for the options enabled. */
155 155
156static void 156static void
157vax_option_override (void) 157vax_option_override (void)
158{ 158{
159 /* We're VAX floating point, not IEEE floating point. */ 159 /* We're VAX floating point, not IEEE floating point. */
160 if (TARGET_G_FLOAT) 160 if (TARGET_G_FLOAT)
161 REAL_MODE_FORMAT (DFmode) = &vax_g_format; 161 REAL_MODE_FORMAT (DFmode) = &vax_g_format;
162 162
163#ifdef SUBTARGET_OVERRIDE_OPTIONS 163#ifdef SUBTARGET_OVERRIDE_OPTIONS
164 SUBTARGET_OVERRIDE_OPTIONS; 164 SUBTARGET_OVERRIDE_OPTIONS;
165#endif 165#endif
166} 166}
167 167
168static void 168static void
169vax_add_reg_cfa_offset (rtx insn, int offset, rtx src) 169vax_add_reg_cfa_offset (rtx insn, int offset, rtx src)
170{ 170{
171 rtx x; 171 rtx x;
172 172
173 x = plus_constant (Pmode, frame_pointer_rtx, offset); 173 x = plus_constant (Pmode, frame_pointer_rtx, offset);
174 x = gen_rtx_MEM (SImode, x); 174 x = gen_rtx_MEM (SImode, x);
175 x = gen_rtx_SET (VOIDmode, x, src); 175 x = gen_rtx_SET (VOIDmode, x, src);
176 add_reg_note (insn, REG_CFA_OFFSET, x); 176 add_reg_note (insn, REG_CFA_OFFSET, x);
177} 177}
178 178
179/* Generate the assembly code for function entry. FILE is a stdio 179/* Generate the assembly code for function entry. FILE is a stdio
180 stream to output the code to. SIZE is an int: how many units of 180 stream to output the code to. SIZE is an int: how many units of
181 temporary storage to allocate. 181 temporary storage to allocate.
182 182
183 Refer to the array `regs_ever_live' to determine which registers to 183 Refer to the array `regs_ever_live' to determine which registers to
184 save; `regs_ever_live[I]' is nonzero if register number I is ever 184 save; `regs_ever_live[I]' is nonzero if register number I is ever
185 used in the function. This function is responsible for knowing 185 used in the function. This function is responsible for knowing
186 which registers should not be saved even if used. */ 186 which registers should not be saved even if used. */
187 187
188void 188void
189vax_expand_prologue (void) 189vax_expand_prologue (void)
190{ 190{
191 int regno, offset; 191 int regno, offset;
192 int mask = 0; 192 int mask = 0;
193 HOST_WIDE_INT size; 193 HOST_WIDE_INT size;
194 rtx insn; 194 rtx insn;
195 195
196 offset = 20; 196 offset = 20;
197 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 197 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
198 if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) 198 if ((df_regs_ever_live_p (regno) && !call_used_regs[regno])
 199 || (crtl->calls_eh_return && regno >= 2 && regno < 4))
199 { 200 {
200 mask |= 1 << regno; 201 mask |= 1 << regno;
201 offset += 4; 202 offset += 4;
202 } 203 }
203 204
204 insn = emit_insn (gen_procedure_entry_mask (GEN_INT (mask))); 205 insn = emit_insn (gen_procedure_entry_mask (GEN_INT (mask)));
205 RTX_FRAME_RELATED_P (insn) = 1; 206 RTX_FRAME_RELATED_P (insn) = 1;
206 207
207 /* The layout of the CALLG/S stack frame is follows: 208 /* The layout of the CALLG/S stack frame is follows:
208 209
209 <- CFA, AP 210 <- CFA, AP
210 r11 211 r11
211 r10 212 r10
212 ... Registers saved as specified by MASK 213 ... Registers saved as specified by MASK
213 r3 214 r3
214 r2 215 r2
215 return-addr 216 return-addr
216 old fp 217 old fp
217 old ap 218 old ap
218 old psw 219 old psw
219 zero 220 zero
220 <- FP, SP 221 <- FP, SP
221 222
222 The rest of the prologue will adjust the SP for the local frame. */ 223 The rest of the prologue will adjust the SP for the local frame. */
223 224
224 add_reg_note (insn, REG_CFA_DEF_CFA, 225 add_reg_note (insn, REG_CFA_DEF_CFA,
225 plus_constant (Pmode, frame_pointer_rtx, offset)); 226 plus_constant (Pmode, frame_pointer_rtx, offset));
226 insn = emit_insn (gen_blockage ()); 227 insn = emit_insn (gen_blockage ());
227 RTX_FRAME_RELATED_P (insn) = 1; 228 RTX_FRAME_RELATED_P (insn) = 1;
228 229
229 vax_add_reg_cfa_offset (insn, 4, gen_rtx_REG (Pmode, PSW_REGNUM)); 230 vax_add_reg_cfa_offset (insn, 4, gen_rtx_REG (Pmode, PSW_REGNUM));
230 vax_add_reg_cfa_offset (insn, 8, arg_pointer_rtx); 231 vax_add_reg_cfa_offset (insn, 8, arg_pointer_rtx);
231 vax_add_reg_cfa_offset (insn, 12, frame_pointer_rtx); 232 vax_add_reg_cfa_offset (insn, 12, frame_pointer_rtx);
232 vax_add_reg_cfa_offset (insn, 16, pc_rtx); 233 vax_add_reg_cfa_offset (insn, 16, pc_rtx);
233 234
234 offset = 20; 235 offset = 20;
235 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 236 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
236 if (mask & (1 << regno)) 237 if (mask & (1 << regno))
237 { 238 {
238 vax_add_reg_cfa_offset (insn, offset, gen_rtx_REG (SImode, regno)); 239 vax_add_reg_cfa_offset (insn, offset, gen_rtx_REG (SImode, regno));
239 offset += 4; 240 offset += 4;
240 } 241 }
241 242
242 /* Allocate the local stack frame. */ 243 /* Allocate the local stack frame. */
243 size = get_frame_size (); 244 size = get_frame_size ();
244 size -= STARTING_FRAME_OFFSET; 245 size -= STARTING_FRAME_OFFSET;
245 emit_insn (gen_addsi3 (stack_pointer_rtx, 246 emit_insn (gen_addsi3 (stack_pointer_rtx,
246 stack_pointer_rtx, GEN_INT (-size))); 247 stack_pointer_rtx, GEN_INT (-size)));
247 248
248 /* Do not allow instructions referencing local stack memory to be 249 /* Do not allow instructions referencing local stack memory to be
249 scheduled before the frame is allocated. This is more pedantic 250 scheduled before the frame is allocated. This is more pedantic
250 than anything else, given that VAX does not currently have a 251 than anything else, given that VAX does not currently have a
251 scheduling description. */ 252 scheduling description. */
252 emit_insn (gen_blockage ()); 253 emit_insn (gen_blockage ());
253} 254}
254 255
255/* When debugging with stabs, we want to output an extra dummy label 256/* When debugging with stabs, we want to output an extra dummy label
256 so that gas can distinguish between D_float and G_float prior to 257 so that gas can distinguish between D_float and G_float prior to
257 processing the .stabs directive identifying type double. */ 258 processing the .stabs directive identifying type double. */
258static void 259static void
259vax_file_start (void) 260vax_file_start (void)
260{ 261{
261 default_file_start (); 262 default_file_start ();
262 263
263 if (write_symbols == DBX_DEBUG) 264 if (write_symbols == DBX_DEBUG)
264 fprintf (asm_out_file, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR); 265 fprintf (asm_out_file, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR);
265} 266}
266 267
267/* We can use the BSD C library routines for the libgcc calls that are 268/* We can use the BSD C library routines for the libgcc calls that are
268 still generated, since that's what they boil down to anyways. When 269 still generated, since that's what they boil down to anyways. When
269 ELF, avoid the user's namespace. */ 270 ELF, avoid the user's namespace. */
270 271
271static void 272static void
272vax_init_libfuncs (void) 273vax_init_libfuncs (void)
273{ 274{
274 if (TARGET_BSD_DIVMOD) 275 if (TARGET_BSD_DIVMOD)
275 { 276 {
276 set_optab_libfunc (udiv_optab, SImode, TARGET_ELF ? "*__udiv" : "*udiv"); 277 set_optab_libfunc (udiv_optab, SImode, TARGET_ELF ? "*__udiv" : "*udiv");
277 set_optab_libfunc (umod_optab, SImode, TARGET_ELF ? "*__urem" : "*urem"); 278 set_optab_libfunc (umod_optab, SImode, TARGET_ELF ? "*__urem" : "*urem");
278 } 279 }
279} 280}
280 281
281/* This is like nonimmediate_operand with a restriction on the type of MEM. */ 282/* This is like nonimmediate_operand with a restriction on the type of MEM. */
282 283
283static void 284static void
284split_quadword_operands (rtx insn, enum rtx_code code, rtx * operands, 285split_quadword_operands (rtx insn, enum rtx_code code, rtx * operands,
285 rtx * low, int n) 286 rtx * low, int n)
286{ 287{
287 int i; 288 int i;
288 289
289 for (i = 0; i < n; i++) 290 for (i = 0; i < n; i++)
290 low[i] = 0; 291 low[i] = 0;
291 292
292 for (i = 0; i < n; i++) 293 for (i = 0; i < n; i++)
293 { 294 {
294 if (MEM_P (operands[i]) 295 if (MEM_P (operands[i])
295 && (GET_CODE (XEXP (operands[i], 0)) == PRE_DEC 296 && (GET_CODE (XEXP (operands[i], 0)) == PRE_DEC
296 || GET_CODE (XEXP (operands[i], 0)) == POST_INC)) 297 || GET_CODE (XEXP (operands[i], 0)) == POST_INC))
297 { 298 {
298 rtx addr = XEXP (operands[i], 0); 299 rtx addr = XEXP (operands[i], 0);
299 operands[i] = low[i] = gen_rtx_MEM (SImode, addr); 300 operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
300 } 301 }
301 else if (optimize_size && MEM_P (operands[i]) 302 else if (optimize_size && MEM_P (operands[i])
302 && REG_P (XEXP (operands[i], 0)) 303 && REG_P (XEXP (operands[i], 0))
303 && (code != MINUS || operands[1] != const0_rtx) 304 && (code != MINUS || operands[1] != const0_rtx)
304 && find_regno_note (insn, REG_DEAD, 305 && find_regno_note (insn, REG_DEAD,
305 REGNO (XEXP (operands[i], 0)))) 306 REGNO (XEXP (operands[i], 0))))
306 { 307 {
307 low[i] = gen_rtx_MEM (SImode, 308 low[i] = gen_rtx_MEM (SImode,
308 gen_rtx_POST_INC (Pmode, 309 gen_rtx_POST_INC (Pmode,
309 XEXP (operands[i], 0))); 310 XEXP (operands[i], 0)));
310 operands[i] = gen_rtx_MEM (SImode, XEXP (operands[i], 0)); 311 operands[i] = gen_rtx_MEM (SImode, XEXP (operands[i], 0));
311 } 312 }
312 else 313 else
313 { 314 {
314 low[i] = operand_subword (operands[i], 0, 0, DImode); 315 low[i] = operand_subword (operands[i], 0, 0, DImode);
315 operands[i] = operand_subword (operands[i], 1, 0, DImode); 316 operands[i] = operand_subword (operands[i], 1, 0, DImode);
316 } 317 }
317 } 318 }
318} 319}
319  320
320void 321void
321print_operand_address (FILE * file, rtx addr) 322print_operand_address (FILE * file, rtx addr)
322{ 323{
323 rtx orig = addr; 324 rtx orig = addr;
324 rtx reg1, breg, ireg; 325 rtx reg1, breg, ireg;
325 rtx offset; 326 rtx offset;
326 327
327 retry: 328 retry:
328 switch (GET_CODE (addr)) 329 switch (GET_CODE (addr))
329 { 330 {
330 case MEM: 331 case MEM:
331 fprintf (file, "*"); 332 fprintf (file, "*");
332 addr = XEXP (addr, 0); 333 addr = XEXP (addr, 0);
333 goto retry; 334 goto retry;
334 335
335 case REG: 336 case REG:
336 fprintf (file, "(%s)", reg_names[REGNO (addr)]); 337 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
337 break; 338 break;
338 339
339 case PRE_DEC: 340 case PRE_DEC:
340 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); 341 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
341 break; 342 break;
342 343
343 case POST_INC: 344 case POST_INC:
344 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); 345 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
345 break; 346 break;
346 347
347 case PLUS: 348 case PLUS:
348 /* There can be either two or three things added here. One must be a 349 /* There can be either two or three things added here. One must be a
349 REG. One can be either a REG or a MULT of a REG and an appropriate 350 REG. One can be either a REG or a MULT of a REG and an appropriate
350 constant, and the third can only be a constant or a MEM. 351 constant, and the third can only be a constant or a MEM.
351 352
352 We get these two or three things and put the constant or MEM in 353 We get these two or three things and put the constant or MEM in
353 OFFSET, the MULT or REG in IREG, and the REG in BREG. If we have 354 OFFSET, the MULT or REG in IREG, and the REG in BREG. If we have
354 a register and can't tell yet if it is a base or index register, 355 a register and can't tell yet if it is a base or index register,
355 put it into REG1. */ 356 put it into REG1. */
356 357
357 reg1 = 0; ireg = 0; breg = 0; offset = 0; 358 reg1 = 0; ireg = 0; breg = 0; offset = 0;
358 359
359 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)) 360 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
360 || MEM_P (XEXP (addr, 0))) 361 || MEM_P (XEXP (addr, 0)))
361 { 362 {
362 offset = XEXP (addr, 0); 363 offset = XEXP (addr, 0);
363 addr = XEXP (addr, 1); 364 addr = XEXP (addr, 1);
364 } 365 }
365 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)) 366 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
366 || MEM_P (XEXP (addr, 1))) 367 || MEM_P (XEXP (addr, 1)))
367 { 368 {
368 offset = XEXP (addr, 1); 369 offset = XEXP (addr, 1);
369 addr = XEXP (addr, 0); 370 addr = XEXP (addr, 0);
370 } 371 }
371 else if (GET_CODE (XEXP (addr, 1)) == MULT) 372 else if (GET_CODE (XEXP (addr, 1)) == MULT)
372 { 373 {
373 ireg = XEXP (addr, 1); 374 ireg = XEXP (addr, 1);
374 addr = XEXP (addr, 0); 375 addr = XEXP (addr, 0);
375 } 376 }
376 else if (GET_CODE (XEXP (addr, 0)) == MULT) 377 else if (GET_CODE (XEXP (addr, 0)) == MULT)
377 { 378 {
378 ireg = XEXP (addr, 0); 379 ireg = XEXP (addr, 0);
379 addr = XEXP (addr, 1); 380 addr = XEXP (addr, 1);
380 } 381 }
381 else if (REG_P (XEXP (addr, 1))) 382 else if (REG_P (XEXP (addr, 1)))
382 { 383 {
383 reg1 = XEXP (addr, 1); 384 reg1 = XEXP (addr, 1);
384 addr = XEXP (addr, 0); 385 addr = XEXP (addr, 0);
385 } 386 }
386 else if (REG_P (XEXP (addr, 0))) 387 else if (REG_P (XEXP (addr, 0)))
387 { 388 {
388 reg1 = XEXP (addr, 0); 389 reg1 = XEXP (addr, 0);
389 addr = XEXP (addr, 1); 390 addr = XEXP (addr, 1);
390 } 391 }
391 else 392 else
392 { 393 {
393 debug_rtx (orig); 394 debug_rtx (orig);
394 gcc_unreachable (); 395 gcc_unreachable ();
395 } 396 }
396 397
397 if (REG_P (addr)) 398 if (REG_P (addr))
398 { 399 {
399 if (reg1) 400 if (reg1)
400 ireg = addr; 401 ireg = addr;
401 else 402 else
402 reg1 = addr; 403 reg1 = addr;
403 } 404 }
404 else if (GET_CODE (addr) == MULT) 405 else if (GET_CODE (addr) == MULT)
405 ireg = addr; 406 ireg = addr;
406 else if (GET_CODE (addr) == PLUS) 407 else if (GET_CODE (addr) == PLUS)
407 { 408 {
408 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)) 409 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
409 || MEM_P (XEXP (addr, 0))) 410 || MEM_P (XEXP (addr, 0)))
410 { 411 {
411 if (offset) 412 if (offset)
412 { 413 {
413 if (CONST_INT_P (offset)) 414 if (CONST_INT_P (offset))
414 offset = plus_constant (Pmode, XEXP (addr, 0), 415 offset = plus_constant (Pmode, XEXP (addr, 0),
415 INTVAL (offset)); 416 INTVAL (offset));
416 else 417 else
417 { 418 {
418 gcc_assert (CONST_INT_P (XEXP (addr, 0))); 419 gcc_assert (CONST_INT_P (XEXP (addr, 0)));
419 offset = plus_constant (Pmode, offset, 420 offset = plus_constant (Pmode, offset,
420 INTVAL (XEXP (addr, 0))); 421 INTVAL (XEXP (addr, 0)));
421 } 422 }
422 } 423 }
423 offset = XEXP (addr, 0); 424 offset = XEXP (addr, 0);
424 } 425 }
425 else if (REG_P (XEXP (addr, 0))) 426 else if (REG_P (XEXP (addr, 0)))
426 { 427 {
427 if (reg1) 428 if (reg1)
428 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0; 429 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
429 else 430 else
430 reg1 = XEXP (addr, 0); 431 reg1 = XEXP (addr, 0);
431 } 432 }
432 else if (GET_CODE (XEXP (addr, 0)) == MULT && !ireg) 433 else if (GET_CODE (XEXP (addr, 0)) == MULT && !ireg)
433 { 434 {
434 ireg = XEXP (addr, 0); 435 ireg = XEXP (addr, 0);
435 } 436 }
436 else 437 else
437 { 438 {
438 debug_rtx (orig); 439 debug_rtx (orig);
439 gcc_unreachable (); 440 gcc_unreachable ();
440 } 441 }
441 442
442 if (CONSTANT_ADDRESS_P (XEXP (addr, 1)) 443 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
443 || MEM_P (XEXP (addr, 1))) 444 || MEM_P (XEXP (addr, 1)))
444 { 445 {
445 if (offset) 446 if (offset)
446 { 447 {
447 if (CONST_INT_P (offset)) 448 if (CONST_INT_P (offset))
448 offset = plus_constant (Pmode, XEXP (addr, 1), 449 offset = plus_constant (Pmode, XEXP (addr, 1),
449 INTVAL (offset)); 450 INTVAL (offset));
450 else 451 else
451 { 452 {
452 gcc_assert (CONST_INT_P (XEXP (addr, 1))); 453 gcc_assert (CONST_INT_P (XEXP (addr, 1)));
453 offset = plus_constant (Pmode, offset, 454 offset = plus_constant (Pmode, offset,
454 INTVAL (XEXP (addr, 1))); 455 INTVAL (XEXP (addr, 1)));
455 } 456 }
456 } 457 }
457 offset = XEXP (addr, 1); 458 offset = XEXP (addr, 1);
458 } 459 }
459 else if (REG_P (XEXP (addr, 1))) 460 else if (REG_P (XEXP (addr, 1)))
460 { 461 {
461 if (reg1) 462 if (reg1)
462 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0; 463 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
463 else 464 else
464 reg1 = XEXP (addr, 1); 465 reg1 = XEXP (addr, 1);
465 } 466 }
466 else if (GET_CODE (XEXP (addr, 1)) == MULT && !ireg) 467 else if (GET_CODE (XEXP (addr, 1)) == MULT && !ireg)
467 { 468 {
468 ireg = XEXP (addr, 1); 469 ireg = XEXP (addr, 1);
469 } 470 }
470 else 471 else
471 { 472 {
472 debug_rtx (orig); 473 debug_rtx (orig);
473 gcc_unreachable (); 474 gcc_unreachable ();
474 } 475 }
475 } 476 }
476 else 477 else
477 { 478 {
478 debug_rtx (orig); 479 debug_rtx (orig);
479 gcc_unreachable (); 480 gcc_unreachable ();
480 } 481 }
481 482
482 /* If REG1 is nonzero, figure out if it is a base or index register. */ 483 /* If REG1 is nonzero, figure out if it is a base or index register. */
483 if (reg1) 484 if (reg1)
484 { 485 {
485 if (breg 486 if (breg
486 || (flag_pic && GET_CODE (addr) == SYMBOL_REF) 487 || (flag_pic && GET_CODE (addr) == SYMBOL_REF)
487 || (offset 488 || (offset
488 && (MEM_P (offset) 489 && (MEM_P (offset)
489 || (flag_pic && symbolic_operand (offset, SImode))))) 490 || (flag_pic && symbolic_operand (offset, SImode)))))
490 { 491 {
491 if (ireg) 492 if (ireg)
492 { 493 {
493 debug_rtx (orig); 494 debug_rtx (orig);
494 gcc_unreachable (); 495 gcc_unreachable ();
495 } 496 }
496 ireg = reg1; 497 ireg = reg1;
497 } 498 }
498 else 499 else
499 breg = reg1; 500 breg = reg1;
500 } 501 }
501 502
502 if (offset != 0) 503 if (offset != 0)
503 { 504 {
504 if (flag_pic && symbolic_operand (offset, SImode)) 505 if (flag_pic && symbolic_operand (offset, SImode))
505 { 506 {
506 if (breg && ireg) 507 if (breg && ireg)
507 { 508 {
508 debug_rtx (orig); 509 debug_rtx (orig);
509 output_operand_lossage ("symbol used with both base and indexed registers"); 510 output_operand_lossage ("symbol used with both base and indexed registers");
510 } 511 }
511 512
512#ifdef NO_EXTERNAL_INDIRECT_ADDRESS 513#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
513 if (flag_pic > 1 && GET_CODE (offset) == CONST 514 if (flag_pic > 1 && GET_CODE (offset) == CONST
514 && GET_CODE (XEXP (XEXP (offset, 0), 0)) == SYMBOL_REF 515 && GET_CODE (XEXP (XEXP (offset, 0), 0)) == SYMBOL_REF
515 && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (offset, 0), 0))) 516 && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (offset, 0), 0)))
516 { 517 {
517 debug_rtx (orig); 518 debug_rtx (orig);
518 output_operand_lossage ("symbol with offset used in PIC mode"); 519 output_operand_lossage ("symbol with offset used in PIC mode");
519 } 520 }
520#endif 521#endif
521 522
522 /* symbol(reg) isn't PIC, but symbol[reg] is. */ 523 /* symbol(reg) isn't PIC, but symbol[reg] is. */
523 if (breg) 524 if (breg)
524 { 525 {
525 ireg = breg; 526 ireg = breg;
526 breg = 0; 527 breg = 0;
527 } 528 }
528 529
529 } 530 }
530 531
531 output_address (offset); 532 output_address (offset);
532 } 533 }
533 534
534 if (breg != 0) 535 if (breg != 0)
535 fprintf (file, "(%s)", reg_names[REGNO (breg)]); 536 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
536 537
537 if (ireg != 0) 538 if (ireg != 0)
538 { 539 {
539 if (GET_CODE (ireg) == MULT) 540 if (GET_CODE (ireg) == MULT)
540 ireg = XEXP (ireg, 0); 541 ireg = XEXP (ireg, 0);
541 if (! REG_P (ireg)) 542 if (! REG_P (ireg))
542 { 543 {
543 debug_rtx (orig); 544 debug_rtx (orig);
544 output_operand_lossage ("non-register index expression"); 545 output_operand_lossage ("non-register index expression");
545 } 546 }
546 fprintf (file, "[%s]", reg_names[REGNO (ireg)]); 547 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
547 } 548 }
548 break; 549 break;
549 550
550 default: 551 default:
551 gcc_assert (! REG_P(addr)); 552 gcc_assert (! REG_P(addr));
552 output_addr_const (file, addr); 553 output_addr_const (file, addr);
553 } 554 }
554} 555}
555 556
556void 557void
557print_operand (FILE *file, rtx x, int code) 558print_operand (FILE *file, rtx x, int code)
558{ 559{
559 if (code == '#') 560 if (code == '#')
560 fputc (ASM_DOUBLE_CHAR, file); 561 fputc (ASM_DOUBLE_CHAR, file);
561 else if (code == '|') 562 else if (code == '|')
562 fputs (REGISTER_PREFIX, file); 563 fputs (REGISTER_PREFIX, file);
563 else if (code == 'c') 564 else if (code == 'c')
564 fputs (cond_name (x), file); 565 fputs (cond_name (x), file);
565 else if (code == 'C') 566 else if (code == 'C')
566 fputs (rev_cond_name (x), file); 567 fputs (rev_cond_name (x), file);
567 else if (code == 'D' && CONST_INT_P (x) && INTVAL (x) < 0) 568 else if (code == 'D' && CONST_INT_P (x) && INTVAL (x) < 0)
568 fprintf (file, "$" NEG_HWI_PRINT_HEX16, INTVAL (x)); 569 fprintf (file, "$" NEG_HWI_PRINT_HEX16, INTVAL (x));
569 else if (code == 'P' && CONST_INT_P (x)) 570 else if (code == 'P' && CONST_INT_P (x))
570 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + 1); 571 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + 1);
571 else if (code == 'N' && CONST_INT_P (x)) 572 else if (code == 'N' && CONST_INT_P (x))
572 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x)); 573 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
573 /* rotl instruction cannot deal with negative arguments. */ 574 /* rotl instruction cannot deal with negative arguments. */
574 else if (code == 'R' && CONST_INT_P (x)) 575 else if (code == 'R' && CONST_INT_P (x))
575 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, 32 - INTVAL (x)); 576 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, 32 - INTVAL (x));
576 else if (code == 'H' && CONST_INT_P (x)) 577 else if (code == 'H' && CONST_INT_P (x))
577 fprintf (file, "$%d", (int) (0xffff & ~ INTVAL (x))); 578 fprintf (file, "$%d", (int) (0xffff & ~ INTVAL (x)));
578 else if (code == 'h' && CONST_INT_P (x)) 579 else if (code == 'h' && CONST_INT_P (x))
579 fprintf (file, "$%d", (short) - INTVAL (x)); 580 fprintf (file, "$%d", (short) - INTVAL (x));
580 else if (code == 'B' && CONST_INT_P (x)) 581 else if (code == 'B' && CONST_INT_P (x))
581 fprintf (file, "$%d", (int) (0xff & ~ INTVAL (x))); 582 fprintf (file, "$%d", (int) (0xff & ~ INTVAL (x)));
582 else if (code == 'b' && CONST_INT_P (x)) 583 else if (code == 'b' && CONST_INT_P (x))
583 fprintf (file, "$%d", (int) (0xff & - INTVAL (x))); 584 fprintf (file, "$%d", (int) (0xff & - INTVAL (x)));
584 else if (code == 'M' && CONST_INT_P (x)) 585 else if (code == 'M' && CONST_INT_P (x))
585 fprintf (file, "$%d", ~((1 << INTVAL (x)) - 1)); 586 fprintf (file, "$%d", ~((1 << INTVAL (x)) - 1));
586 else if (code == 'x' && CONST_INT_P (x)) 587 else if (code == 'x' && CONST_INT_P (x))
587 fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x)); 588 fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
588 else if (REG_P (x)) 589 else if (REG_P (x))
589 fprintf (file, "%s", reg_names[REGNO (x)]); 590 fprintf (file, "%s", reg_names[REGNO (x)]);
590 else if (MEM_P (x)) 591 else if (MEM_P (x))
591 output_address (XEXP (x, 0)); 592 output_address (XEXP (x, 0));
592 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode) 593 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
593 { 594 {
594 char dstr[30]; 595 char dstr[30];
595 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), 596 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x),
596 sizeof (dstr), 0, 1); 597 sizeof (dstr), 0, 1);
597 fprintf (file, "$0f%s", dstr); 598 fprintf (file, "$0f%s", dstr);
598 } 599 }
599 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode) 600 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
600 { 601 {
601 char dstr[30]; 602 char dstr[30];
602 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), 603 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x),
603 sizeof (dstr), 0, 1); 604 sizeof (dstr), 0, 1);
604 fprintf (file, "$0%c%s", ASM_DOUBLE_CHAR, dstr); 605 fprintf (file, "$0%c%s", ASM_DOUBLE_CHAR, dstr);
605 } 606 }
606 else if (GET_CODE (x) == SUBREG) 607 else if (GET_CODE (x) == SUBREG)
607 { 608 {
608 debug_rtx (x); 609 debug_rtx (x);
609 output_operand_lossage ("SUBREG operand"); 610 output_operand_lossage ("SUBREG operand");
610 } 611 }
611 else 612 else
612 { 613 {
613 if (flag_pic > 1 && symbolic_operand (x, SImode)) 614 if (flag_pic > 1 && symbolic_operand (x, SImode))
614 { 615 {
615 debug_rtx (x); 616 debug_rtx (x);
616 output_operand_lossage ("symbol used as immediate operand"); 617 output_operand_lossage ("symbol used as immediate operand");
617 } 618 }
618 putc ('$', file); 619 putc ('$', file);
619 output_addr_const (file, x); 620 output_addr_const (file, x);
620 } 621 }
621} 622}
622  623
623const char * 624const char *
624cond_name (rtx op) 625cond_name (rtx op)
625{ 626{
626 switch (GET_CODE (op)) 627 switch (GET_CODE (op))
627 { 628 {
628 case NE: 629 case NE:
629 return "neq"; 630 return "neq";
630 case EQ: 631 case EQ:
631 return "eql"; 632 return "eql";
632 case GE: 633 case GE:
633 return "geq"; 634 return "geq";
634 case GT: 635 case GT:
635 return "gtr"; 636 return "gtr";
636 case LE: 637 case LE:
637 return "leq"; 638 return "leq";
638 case LT: 639 case LT:
639 return "lss"; 640 return "lss";
640 case GEU: 641 case GEU:
641 return "gequ"; 642 return "gequ";
642 case GTU: 643 case GTU:
643 return "gtru"; 644 return "gtru";
644 case LEU: 645 case LEU:
645 return "lequ"; 646 return "lequ";
646 case LTU: 647 case LTU:
647 return "lssu"; 648 return "lssu";
648 649
649 default: 650 default:
650 gcc_unreachable (); 651 gcc_unreachable ();
651 } 652 }
652} 653}
653 654
654const char * 655const char *
655rev_cond_name (rtx op) 656rev_cond_name (rtx op)
656{ 657{
657 switch (GET_CODE (op)) 658 switch (GET_CODE (op))
658 { 659 {
659 case EQ: 660 case EQ:
660 return "neq"; 661 return "neq";
661 case NE: 662 case NE:
662 return "eql"; 663 return "eql";
663 case LT: 664 case LT:
664 return "geq"; 665 return "geq";
665 case LE: 666 case LE:
666 return "gtr"; 667 return "gtr";
667 case GT: 668 case GT:
668 return "leq"; 669 return "leq";
669 case GE: 670 case GE:
670 return "lss"; 671 return "lss";
671 case LTU: 672 case LTU:
672 return "gequ"; 673 return "gequ";
673 case LEU: 674 case LEU:
674 return "gtru"; 675 return "gtru";
675 case GTU: 676 case GTU:
676 return "lequ"; 677 return "lequ";
677 case GEU: 678 case GEU:
678 return "lssu"; 679 return "lssu";
679 680
680 default: 681 default:
681 gcc_unreachable (); 682 gcc_unreachable ();
682 } 683 }
683} 684}
684 685
685static bool 686static bool
686vax_float_literal (rtx c) 687vax_float_literal (rtx c)
687{ 688{
688 machine_mode mode; 689 machine_mode mode;
689 REAL_VALUE_TYPE r, s; 690 REAL_VALUE_TYPE r, s;
690 int i; 691 int i;
691 692
692 if (GET_CODE (c) != CONST_DOUBLE) 693 if (GET_CODE (c) != CONST_DOUBLE)
693 return false; 694 return false;
694 695
695 mode = GET_MODE (c); 696 mode = GET_MODE (c);
696 697
697 if (c == const_tiny_rtx[(int) mode][0] 698 if (c == const_tiny_rtx[(int) mode][0]
698 || c == const_tiny_rtx[(int) mode][1] 699 || c == const_tiny_rtx[(int) mode][1]
699 || c == const_tiny_rtx[(int) mode][2]) 700 || c == const_tiny_rtx[(int) mode][2])
700 return true; 701 return true;
701 702
702 REAL_VALUE_FROM_CONST_DOUBLE (r, c); 703 REAL_VALUE_FROM_CONST_DOUBLE (r, c);
703 704
704 for (i = 0; i < 7; i++) 705 for (i = 0; i < 7; i++)
705 { 706 {
706 int x = 1 << i; 707 int x = 1 << i;
707 bool ok; 708 bool ok;
708 real_from_integer (&s, mode, x, SIGNED); 709 real_from_integer (&s, mode, x, SIGNED);
709 710
710 if (REAL_VALUES_EQUAL (r, s)) 711 if (REAL_VALUES_EQUAL (r, s))
711 return true; 712 return true;
712 ok = exact_real_inverse (mode, &s); 713 ok = exact_real_inverse (mode, &s);
713 gcc_assert (ok); 714 gcc_assert (ok);
714 if (REAL_VALUES_EQUAL (r, s)) 715 if (REAL_VALUES_EQUAL (r, s))
715 return true; 716 return true;
716 } 717 }
717 return false; 718 return false;
718} 719}
719 720
720 721
721/* Return the cost in cycles of a memory address, relative to register 722/* Return the cost in cycles of a memory address, relative to register
722 indirect. 723 indirect.
723 724
724 Each of the following adds the indicated number of cycles: 725 Each of the following adds the indicated number of cycles:
725 726
726 1 - symbolic address 727 1 - symbolic address
727 1 - pre-decrement 728 1 - pre-decrement
728 1 - indexing and/or offset(register) 729 1 - indexing and/or offset(register)
729 2 - indirect */ 730 2 - indirect */
730 731
731 732
732static int 733static int
733vax_address_cost_1 (rtx addr) 734vax_address_cost_1 (rtx addr)
734{ 735{
735 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0; 736 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
736 rtx plus_op0 = 0, plus_op1 = 0; 737 rtx plus_op0 = 0, plus_op1 = 0;
737 restart: 738 restart:
738 switch (GET_CODE (addr)) 739 switch (GET_CODE (addr))
739 { 740 {
740 case PRE_DEC: 741 case PRE_DEC:
741 predec = 1; 742 predec = 1;
742 case REG: 743 case REG:
743 case SUBREG: 744 case SUBREG:
744 case POST_INC: 745 case POST_INC:
745 reg = 1; 746 reg = 1;
746 break; 747 break;
747 case MULT: 748 case MULT:
748 indexed = 1; /* 2 on VAX 2 */ 749 indexed = 1; /* 2 on VAX 2 */
749 break; 750 break;
750 case CONST_INT: 751 case CONST_INT:
751 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */ 752 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
752 if (offset == 0) 753 if (offset == 0)
753 offset = (unsigned HOST_WIDE_INT)(INTVAL(addr)+128) > 256; 754 offset = (unsigned HOST_WIDE_INT)(INTVAL(addr)+128) > 256;
754 break; 755 break;
755 case CONST: 756 case CONST:
756 case SYMBOL_REF: 757 case SYMBOL_REF:
757 offset = 1; /* 2 on VAX 2 */ 758 offset = 1; /* 2 on VAX 2 */
758 break; 759 break;
759 case LABEL_REF: /* this is probably a byte offset from the pc */ 760 case LABEL_REF: /* this is probably a byte offset from the pc */
760 if (offset == 0) 761 if (offset == 0)
761 offset = 1; 762 offset = 1;
762 break; 763 break;
763 case PLUS: 764 case PLUS:
764 if (plus_op0) 765 if (plus_op0)
765 plus_op1 = XEXP (addr, 0); 766 plus_op1 = XEXP (addr, 0);
766 else 767 else
767 plus_op0 = XEXP (addr, 0); 768 plus_op0 = XEXP (addr, 0);
768 addr = XEXP (addr, 1); 769 addr = XEXP (addr, 1);
769 goto restart; 770 goto restart;
770 case MEM: 771 case MEM:
771 indir = 2; /* 3 on VAX 2 */ 772 indir = 2; /* 3 on VAX 2 */
772 addr = XEXP (addr, 0); 773 addr = XEXP (addr, 0);
773 goto restart; 774 goto restart;
774 default: 775 default:
775 break; 776 break;
776 } 777 }
777 778
778 /* Up to 3 things can be added in an address. They are stored in 779 /* Up to 3 things can be added in an address. They are stored in
779 plus_op0, plus_op1, and addr. */ 780 plus_op0, plus_op1, and addr. */
780 781
781 if (plus_op0) 782 if (plus_op0)
782 { 783 {
783 addr = plus_op0; 784 addr = plus_op0;
784 plus_op0 = 0; 785 plus_op0 = 0;
785 goto restart; 786 goto restart;
786 } 787 }
787 if (plus_op1) 788 if (plus_op1)
788 { 789 {
789 addr = plus_op1; 790 addr = plus_op1;
790 plus_op1 = 0; 791 plus_op1 = 0;
791 goto restart; 792 goto restart;
792 } 793 }
793 /* Indexing and register+offset can both be used (except on a VAX 2) 794 /* Indexing and register+offset can both be used (except on a VAX 2)
794 without increasing execution time over either one alone. */ 795 without increasing execution time over either one alone. */
795 if (reg && indexed && offset) 796 if (reg && indexed && offset)
796 return reg + indir + offset + predec; 797 return reg + indir + offset + predec;
797 return reg + indexed + indir + offset + predec; 798 return reg + indexed + indir + offset + predec;
798} 799}
799 800
800static int 801static int
801vax_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED, 802vax_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
802 addr_space_t as ATTRIBUTE_UNUSED, 803 addr_space_t as ATTRIBUTE_UNUSED,
803 bool speed ATTRIBUTE_UNUSED) 804 bool speed ATTRIBUTE_UNUSED)
804{ 805{
805 return (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x))); 806 return (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x)));
806} 807}
807 808
808/* Cost of an expression on a VAX. This version has costs tuned for the 809/* Cost of an expression on a VAX. This version has costs tuned for the
809 CVAX chip (found in the VAX 3 series) with comments for variations on 810 CVAX chip (found in the VAX 3 series) with comments for variations on
810 other models. 811 other models.
811 812
812 FIXME: The costs need review, particularly for TRUNCATE, FLOAT_EXTEND 813 FIXME: The costs need review, particularly for TRUNCATE, FLOAT_EXTEND
813 and FLOAT_TRUNCATE. We need a -mcpu option to allow provision of 814 and FLOAT_TRUNCATE. We need a -mcpu option to allow provision of
814 costs on a per cpu basis. */ 815 costs on a per cpu basis. */
815 816
816static bool 817static bool
817vax_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, 818vax_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
818 int *total, bool speed ATTRIBUTE_UNUSED) 819 int *total, bool speed ATTRIBUTE_UNUSED)
819{ 820{
820 machine_mode mode = GET_MODE (x); 821 machine_mode mode = GET_MODE (x);
821 int i = 0; /* may be modified in switch */ 822 int i = 0; /* may be modified in switch */
822 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */ 823 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
823 824
824 switch (code) 825 switch (code)
825 { 826 {
826 /* On a VAX, constants from 0..63 are cheap because they can use the 827 /* On a VAX, constants from 0..63 are cheap because they can use the
827 1 byte literal constant format. Compare to -1 should be made cheap 828 1 byte literal constant format. Compare to -1 should be made cheap
828 so that decrement-and-branch insns can be formed more easily (if 829 so that decrement-and-branch insns can be formed more easily (if
829 the value -1 is copied to a register some decrement-and-branch 830 the value -1 is copied to a register some decrement-and-branch
830 patterns will not match). */ 831 patterns will not match). */
831 case CONST_INT: 832 case CONST_INT:
832 if (INTVAL (x) == 0) 833 if (INTVAL (x) == 0)
833 { 834 {
834 *total = 0; 835 *total = 0;
835 return true; 836 return true;
836 } 837 }
837 if (outer_code == AND) 838 if (outer_code == AND)
838 { 839 {
839 *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2; 840 *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2;
840 return true; 841 return true;
841 } 842 }
842 if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077 843 if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077
843 || (outer_code == COMPARE 844 || (outer_code == COMPARE
844 && INTVAL (x) == -1) 845 && INTVAL (x) == -1)
845 || ((outer_code == PLUS || outer_code == MINUS) 846 || ((outer_code == PLUS || outer_code == MINUS)
846 && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077)) 847 && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077))
847 { 848 {
848 *total = 1; 849 *total = 1;
849 return true; 850 return true;
850 } 851 }
851 /* FALLTHRU */ 852 /* FALLTHRU */
852 853
853 case CONST: 854 case CONST:
854 case LABEL_REF: 855 case LABEL_REF:
855 case SYMBOL_REF: 856 case SYMBOL_REF:
856 *total = 3; 857 *total = 3;
857 return true; 858 return true;
858 859
859 case CONST_DOUBLE: 860 case CONST_DOUBLE:
860 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) 861 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
861 *total = vax_float_literal (x) ? 5 : 8; 862 *total = vax_float_literal (x) ? 5 : 8;
862 else 863 else
863 *total = ((CONST_DOUBLE_HIGH (x) == 0 864 *total = ((CONST_DOUBLE_HIGH (x) == 0
864 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64) 865 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64)
865 || (outer_code == PLUS 866 || (outer_code == PLUS
866 && CONST_DOUBLE_HIGH (x) == -1 867 && CONST_DOUBLE_HIGH (x) == -1
867 && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64)) 868 && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64))
868 ? 2 : 5; 869 ? 2 : 5;
869 return true; 870 return true;
870 871
871 case POST_INC: 872 case POST_INC:
872 *total = 2; 873 *total = 2;
873 return true; /* Implies register operand. */ 874 return true; /* Implies register operand. */
874 875
875 case PRE_DEC: 876 case PRE_DEC:
876 *total = 3; 877 *total = 3;
877 return true; /* Implies register operand. */ 878 return true; /* Implies register operand. */
878 879
879 case MULT: 880 case MULT:
880 switch (mode) 881 switch (mode)
881 { 882 {
882 case DFmode: 883 case DFmode:
883 *total = 16; /* 4 on VAX 9000 */ 884 *total = 16; /* 4 on VAX 9000 */
884 break; 885 break;
885 case SFmode: 886 case SFmode:
886 *total = 9; /* 4 on VAX 9000, 12 on VAX 2 */ 887 *total = 9; /* 4 on VAX 9000, 12 on VAX 2 */
887 break; 888 break;
888 case DImode: 889 case DImode:
889 *total = 16; /* 6 on VAX 9000, 28 on VAX 2 */ 890 *total = 16; /* 6 on VAX 9000, 28 on VAX 2 */
890 break; 891 break;
891 case SImode: 892 case SImode:
892 case HImode: 893 case HImode:
893 case QImode: 894 case QImode:
894 *total = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */ 895 *total = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
895 break; 896 break;
896 default: 897 default:
897 *total = MAX_COST; /* Mode is not supported. */ 898 *total = MAX_COST; /* Mode is not supported. */
898 return true; 899 return true;
899 } 900 }
900 break; 901 break;
901 902
902 case UDIV: 903 case UDIV:
903 if (mode != SImode) 904 if (mode != SImode)
904 { 905 {
905 *total = MAX_COST; /* Mode is not supported. */ 906 *total = MAX_COST; /* Mode is not supported. */
906 return true; 907 return true;
907 } 908 }
908 *total = 17; 909 *total = 17;
909 break; 910 break;
910 911
911 case DIV: 912 case DIV:
912 if (mode == DImode) 913 if (mode == DImode)
913 *total = 30; /* Highly variable. */ 914 *total = 30; /* Highly variable. */
914 else if (mode == DFmode) 915 else if (mode == DFmode)
915 /* divide takes 28 cycles if the result is not zero, 13 otherwise */ 916 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
916 *total = 24; 917 *total = 24;
917 else 918 else
918 *total = 11; /* 25 on VAX 2 */ 919 *total = 11; /* 25 on VAX 2 */
919 break; 920 break;
920 921
921 case MOD: 922 case MOD:
922 *total = 23; 923 *total = 23;
923 break; 924 break;
924 925
925 case UMOD: 926 case UMOD:
926 if (mode != SImode) 927 if (mode != SImode)
927 { 928 {
928 *total = MAX_COST; /* Mode is not supported. */ 929 *total = MAX_COST; /* Mode is not supported. */
929 return true; 930 return true;
930 } 931 }
931 *total = 29; 932 *total = 29;
932 break; 933 break;
933 934
934 case FLOAT: 935 case FLOAT:
935 *total = (6 /* 4 on VAX 9000 */ 936 *total = (6 /* 4 on VAX 9000 */
936 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode)); 937 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode));
937 break; 938 break;
938 939
939 case FIX: 940 case FIX:
940 *total = 7; /* 17 on VAX 2 */ 941 *total = 7; /* 17 on VAX 2 */
941 break; 942 break;
942 943
943 case ASHIFT: 944 case ASHIFT:
944 case LSHIFTRT: 945 case LSHIFTRT:
945 case ASHIFTRT: 946 case ASHIFTRT:
946 if (mode == DImode) 947 if (mode == DImode)
947 *total = 12; 948 *total = 12;
948 else 949 else
949 *total = 10; /* 6 on VAX 9000 */ 950 *total = 10; /* 6 on VAX 9000 */
950 break; 951 break;
951 952
952 case ROTATE: 953 case ROTATE:
953 case ROTATERT: 954 case ROTATERT:
954 *total = 6; /* 5 on VAX 2, 4 on VAX 9000 */ 955 *total = 6; /* 5 on VAX 2, 4 on VAX 9000 */
955 if (CONST_INT_P (XEXP (x, 1))) 956 if (CONST_INT_P (XEXP (x, 1)))
956 fmt = "e"; /* all constant rotate counts are short */ 957 fmt = "e"; /* all constant rotate counts are short */
957 break; 958 break;
958 959
959 case PLUS: 960 case PLUS:
960 case MINUS: 961 case MINUS:
961 *total = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */ 962 *total = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
962 /* Small integer operands can use subl2 and addl2. */ 963 /* Small integer operands can use subl2 and addl2. */
963 if ((CONST_INT_P (XEXP (x, 1))) 964 if ((CONST_INT_P (XEXP (x, 1)))
964 && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127) 965 && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127)
965 fmt = "e"; 966 fmt = "e";
966 break; 967 break;
967 968
968 case IOR: 969 case IOR:
969 case XOR: 970 case XOR:
970 *total = 3; 971 *total = 3;
971 break; 972 break;
972 973
973 case AND: 974 case AND:
974 /* AND is special because the first operand is complemented. */ 975 /* AND is special because the first operand is complemented. */
975 *total = 3; 976 *total = 3;
976 if (CONST_INT_P (XEXP (x, 0))) 977 if (CONST_INT_P (XEXP (x, 0)))
977 { 978 {
978 if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63) 979 if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63)
979 *total = 4; 980 *total = 4;
980 fmt = "e"; 981 fmt = "e";
981 i = 1; 982 i = 1;
982 } 983 }
983 break; 984 break;
984 985
985 case NEG: 986 case NEG:
986 if (mode == DFmode) 987 if (mode == DFmode)
987 *total = 9; 988 *total = 9;
988 else if (mode == SFmode) 989 else if (mode == SFmode)
989 *total = 6; 990 *total = 6;
990 else if (mode == DImode) 991 else if (mode == DImode)
991 *total = 4; 992 *total = 4;
992 else 993 else
993 *total = 2; 994 *total = 2;
994 break; 995 break;
995 996
996 case NOT: 997 case NOT:
997 *total = 2; 998 *total = 2;
998 break; 999 break;
999 1000
1000 case ZERO_EXTRACT: 1001 case ZERO_EXTRACT:
1001 case SIGN_EXTRACT: 1002 case SIGN_EXTRACT:
1002 *total = 15; 1003 *total = 15;
1003 break; 1004 break;
1004 1005
1005 case MEM: 1006 case MEM:
1006 if (mode == DImode || mode == DFmode) 1007 if (mode == DImode || mode == DFmode)
1007 *total = 5; /* 7 on VAX 2 */ 1008 *total = 5; /* 7 on VAX 2 */
1008 else 1009 else
1009 *total = 3; /* 4 on VAX 2 */ 1010 *total = 3; /* 4 on VAX 2 */
1010 x = XEXP (x, 0); 1011 x = XEXP (x, 0);
1011 if (!REG_P (x) && GET_CODE (x) != POST_INC) 1012 if (!REG_P (x) && GET_CODE (x) != POST_INC)
1012 *total += vax_address_cost_1 (x); 1013 *total += vax_address_cost_1 (x);
1013 return true; 1014 return true;
1014 1015
1015 case FLOAT_EXTEND: 1016 case FLOAT_EXTEND:
1016 case FLOAT_TRUNCATE: 1017 case FLOAT_TRUNCATE:
1017 case TRUNCATE: 1018 case TRUNCATE:
1018 *total = 3; /* FIXME: Costs need to be checked */ 1019 *total = 3; /* FIXME: Costs need to be checked */
1019 break; 1020 break;
1020 1021
1021 default: 1022 default:
1022 return false; 1023 return false;
1023 } 1024 }
1024 1025
1025 /* Now look inside the expression. Operands which are not registers or 1026 /* Now look inside the expression. Operands which are not registers or
1026 short constants add to the cost. 1027 short constants add to the cost.
1027 1028
1028 FMT and I may have been adjusted in the switch above for instructions 1029 FMT and I may have been adjusted in the switch above for instructions
1029 which require special handling. */ 1030 which require special handling. */
1030 1031
1031 while (*fmt++ == 'e') 1032 while (*fmt++ == 'e')
1032 { 1033 {
1033 rtx op = XEXP (x, i); 1034 rtx op = XEXP (x, i);
1034 1035
1035 i += 1; 1036 i += 1;
1036 code = GET_CODE (op); 1037 code = GET_CODE (op);
1037 1038
1038 /* A NOT is likely to be found as the first operand of an AND 1039 /* A NOT is likely to be found as the first operand of an AND
1039 (in which case the relevant cost is of the operand inside 1040 (in which case the relevant cost is of the operand inside
1040 the not) and not likely to be found anywhere else. */ 1041 the not) and not likely to be found anywhere else. */
1041 if (code == NOT) 1042 if (code == NOT)
1042 op = XEXP (op, 0), code = GET_CODE (op); 1043 op = XEXP (op, 0), code = GET_CODE (op);
1043 1044
1044 switch (code) 1045 switch (code)
1045 { 1046 {
1046 case CONST_INT: 1047 case CONST_INT:
1047 if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63 1048 if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63
1048 && GET_MODE (x) != QImode) 1049 && GET_MODE (x) != QImode)
1049 *total += 1; /* 2 on VAX 2 */ 1050 *total += 1; /* 2 on VAX 2 */
1050 break; 1051 break;
1051 case CONST: 1052 case CONST:
1052 case LABEL_REF: 1053 case LABEL_REF:
1053 case SYMBOL_REF: 1054 case SYMBOL_REF:
1054 *total += 1; /* 2 on VAX 2 */ 1055 *total += 1; /* 2 on VAX 2 */
1055 break; 1056 break;
1056 case CONST_DOUBLE: 1057 case CONST_DOUBLE:
1057 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT) 1058 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
1058 { 1059 {
1059 /* Registers are faster than floating point constants -- even 1060 /* Registers are faster than floating point constants -- even
1060 those constants which can be encoded in a single byte. */ 1061 those constants which can be encoded in a single byte. */
1061 if (vax_float_literal (op)) 1062 if (vax_float_literal (op))
1062 *total += 1; 1063 *total += 1;
1063 else 1064 else
1064 *total += (GET_MODE (x) == DFmode) ? 3 : 2; 1065 *total += (GET_MODE (x) == DFmode) ? 3 : 2;
1065 } 1066 }
1066 else 1067 else
1067 { 1068 {
1068 if (CONST_DOUBLE_HIGH (op) != 0 1069 if (CONST_DOUBLE_HIGH (op) != 0
1069 || (unsigned HOST_WIDE_INT)CONST_DOUBLE_LOW (op) > 63) 1070 || (unsigned HOST_WIDE_INT)CONST_DOUBLE_LOW (op) > 63)
1070 *total += 2; 1071 *total += 2;
1071 } 1072 }
1072 break; 1073 break;
1073 case MEM: 1074 case MEM:
1074 *total += 1; /* 2 on VAX 2 */ 1075 *total += 1; /* 2 on VAX 2 */
1075 if (!REG_P (XEXP (op, 0))) 1076 if (!REG_P (XEXP (op, 0)))
1076 *total += vax_address_cost_1 (XEXP (op, 0)); 1077 *total += vax_address_cost_1 (XEXP (op, 0));
1077 break; 1078 break;
1078 case REG: 1079 case REG:
1079 case SUBREG: 1080 case SUBREG:
1080 break; 1081 break;
1081 default: 1082 default:
1082 *total += 1; 1083 *total += 1;
1083 break; 1084 break;
1084 } 1085 }
1085 } 1086 }
1086 return true; 1087 return true;
1087} 1088}
1088  1089
1089/* Output code to add DELTA to the first argument, and then jump to FUNCTION. 1090/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
1090 Used for C++ multiple inheritance. 1091 Used for C++ multiple inheritance.
1091 .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask 1092 .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask
1092 addl2 $DELTA, 4(ap) #adjust first argument 1093 addl2 $DELTA, 4(ap) #adjust first argument
1093 jmp FUNCTION+2 #jump beyond FUNCTION's entry mask 1094 jmp FUNCTION+2 #jump beyond FUNCTION's entry mask
1094*/ 1095*/
1095 1096
1096static void 1097static void
1097vax_output_mi_thunk (FILE * file, 1098vax_output_mi_thunk (FILE * file,
1098 tree thunk ATTRIBUTE_UNUSED, 1099 tree thunk ATTRIBUTE_UNUSED,
1099 HOST_WIDE_INT delta, 1100 HOST_WIDE_INT delta,
1100 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED, 1101 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1101 tree function) 1102 tree function)
1102{ 1103{
1103 fprintf (file, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC, delta); 1104 fprintf (file, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC, delta);
1104 asm_fprintf (file, ",4(%Rap)\n"); 1105 asm_fprintf (file, ",4(%Rap)\n");
1105 fprintf (file, "\tjmp "); 1106 fprintf (file, "\tjmp ");
1106 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); 1107 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1107 fprintf (file, "+2\n"); 1108 fprintf (file, "+2\n");
1108} 1109}
1109  1110
1110static rtx 1111static rtx
1111vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, 1112vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
1112 int incoming ATTRIBUTE_UNUSED) 1113 int incoming ATTRIBUTE_UNUSED)
1113{ 1114{
1114 return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM); 1115 return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM);
1115} 1116}
1116 1117
1117static rtx 1118static rtx
1118vax_builtin_setjmp_frame_value (void) 1119vax_builtin_setjmp_frame_value (void)
1119{ 1120{
1120 return hard_frame_pointer_rtx; 1121 return hard_frame_pointer_rtx;
1121} 1122}
1122 1123
1123/* Worker function for NOTICE_UPDATE_CC. */ 1124/* Worker function for NOTICE_UPDATE_CC. */
1124 1125
1125void 1126void
1126vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED) 1127vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
1127{ 1128{
1128 if (GET_CODE (exp) == SET) 1129 if (GET_CODE (exp) == SET)
1129 { 1130 {
1130 if (GET_CODE (SET_SRC (exp)) == CALL) 1131 if (GET_CODE (SET_SRC (exp)) == CALL)
1131 CC_STATUS_INIT; 1132 CC_STATUS_INIT;
1132 else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT 1133 else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT
1133 && GET_CODE (SET_DEST (exp)) != PC) 1134 && GET_CODE (SET_DEST (exp)) != PC)
1134 { 1135 {
1135 cc_status.flags = 0; 1136 cc_status.flags = 0;
1136 /* The integer operations below don't set carry or 1137 /* The integer operations below don't set carry or
1137 set it in an incompatible way. That's ok though 1138 set it in an incompatible way. That's ok though
1138 as the Z bit is all we need when doing unsigned 1139 as the Z bit is all we need when doing unsigned
1139 comparisons on the result of these insns (since 1140 comparisons on the result of these insns (since
1140 they're always with 0). Set CC_NO_OVERFLOW to 1141 they're always with 0). Set CC_NO_OVERFLOW to
1141 generate the correct unsigned branches. */ 1142 generate the correct unsigned branches. */
1142 switch (GET_CODE (SET_SRC (exp))) 1143 switch (GET_CODE (SET_SRC (exp)))
1143 { 1144 {
1144 case NEG: 1145 case NEG:
1145 if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT) 1146 if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT)
1146 break; 1147 break;
1147 case AND: 1148 case AND:
1148 case IOR: 1149 case IOR:
1149 case XOR: 1150 case XOR:
1150 case NOT: 1151 case NOT:
1151 case CTZ: 1152 case CTZ:
1152 case MEM: 1153 case MEM:
1153 case REG: 1154 case REG:
1154 cc_status.flags = CC_NO_OVERFLOW; 1155 cc_status.flags = CC_NO_OVERFLOW;
1155 break; 1156 break;
1156 default: 1157 default:
1157 break; 1158 break;
1158 } 1159 }
1159 cc_status.value1 = SET_DEST (exp); 1160 cc_status.value1 = SET_DEST (exp);
1160 cc_status.value2 = SET_SRC (exp); 1161 cc_status.value2 = SET_SRC (exp);
1161 } 1162 }
1162 } 1163 }
1163 else if (GET_CODE (exp) == PARALLEL 1164 else if (GET_CODE (exp) == PARALLEL
1164 && GET_CODE (XVECEXP (exp, 0, 0)) == SET) 1165 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1165 { 1166 {
1166 if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL) 1167 if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL)
1167 CC_STATUS_INIT; 1168 CC_STATUS_INIT;
1168 else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC) 1169 else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC)
1169 { 1170 {
1170 cc_status.flags = 0; 1171 cc_status.flags = 0;
1171 cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0)); 1172 cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0));
1172 cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0)); 1173 cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0));
1173 } 1174 }
1174 else 1175 else
1175 /* PARALLELs whose first element sets the PC are aob, 1176 /* PARALLELs whose first element sets the PC are aob,
1176 sob insns. They do change the cc's. */ 1177 sob insns. They do change the cc's. */
1177 CC_STATUS_INIT; 1178 CC_STATUS_INIT;
1178 } 1179 }
1179 else 1180 else
1180 CC_STATUS_INIT; 1181 CC_STATUS_INIT;
1181 if (cc_status.value1 && REG_P (cc_status.value1) 1182 if (cc_status.value1 && REG_P (cc_status.value1)
1182 && cc_status.value2 1183 && cc_status.value2
1183 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) 1184 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1184 cc_status.value2 = 0; 1185 cc_status.value2 = 0;
1185 if (cc_status.value1 && MEM_P (cc_status.value1) 1186 if (cc_status.value1 && MEM_P (cc_status.value1)
1186 && cc_status.value2 1187 && cc_status.value2
1187 && MEM_P (cc_status.value2)) 1188 && MEM_P (cc_status.value2))
1188 cc_status.value2 = 0; 1189 cc_status.value2 = 0;
1189 /* Actual condition, one line up, should be that value2's address 1190 /* Actual condition, one line up, should be that value2's address
1190 depends on value1, but that is too much of a pain. */ 1191 depends on value1, but that is too much of a pain. */
1191} 1192}
1192 1193
1193/* Output integer move instructions. */ 1194/* Output integer move instructions. */
1194 1195
1195const char * 1196const char *
1196vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, 1197vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
1197 machine_mode mode) 1198 machine_mode mode)

cvs diff -r1.5 -r1.6 src/external/gpl3/gcc/dist/gcc/config/vax/vax.h (switch to unified diff)

--- src/external/gpl3/gcc/dist/gcc/config/vax/vax.h 2016/03/23 12:45:50 1.5
+++ src/external/gpl3/gcc/dist/gcc/config/vax/vax.h 2016/03/23 12:52:43 1.6
@@ -1,716 +1,716 @@ @@ -1,716 +1,716 @@
1/* Definitions of target machine for GNU compiler. VAX version. 1/* Definitions of target machine for GNU compiler. VAX version.
2 Copyright (C) 1987-2015 Free Software Foundation, Inc. 2 Copyright (C) 1987-2015 Free Software Foundation, Inc.
3 3
4This file is part of GCC. 4This file is part of GCC.
5 5
6GCC is free software; you can redistribute it and/or modify 6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by 7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option) 8the Free Software Foundation; either version 3, or (at your option)
9any later version. 9any later version.
10 10
11GCC is distributed in the hope that it will be useful, 11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of 12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details. 14GNU General Public License for more details.
15 15
16You should have received a copy of the GNU General Public License 16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */ 18<http://www.gnu.org/licenses/>. */
19 19
20#include "vax-protos.h" 20#include "vax-protos.h"
21 21
22/* Target CPU builtins. */ 22/* Target CPU builtins. */
23#define TARGET_CPU_CPP_BUILTINS() \ 23#define TARGET_CPU_CPP_BUILTINS() \
24 do \ 24 do \
25 { \ 25 { \
26 builtin_define ("__vax__"); \ 26 builtin_define ("__vax__"); \
27 builtin_assert ("cpu=vax"); \ 27 builtin_assert ("cpu=vax"); \
28 builtin_assert ("machine=vax"); \ 28 builtin_assert ("machine=vax"); \
29 if (TARGET_G_FLOAT) \ 29 if (TARGET_G_FLOAT) \
30 { \ 30 { \
31 builtin_define ("__GFLOAT"); \ 31 builtin_define ("__GFLOAT"); \
32 builtin_define ("__GFLOAT__"); \ 32 builtin_define ("__GFLOAT__"); \
33 } \ 33 } \
34 } \ 34 } \
35 while (0) 35 while (0)
36 36
37/* Use -J option for long branch support with Unix assembler. */ 37/* Use -J option for long branch support with Unix assembler. */
38 38
39#define ASM_SPEC "-J" 39#define ASM_SPEC "-J"
40 40
41/* Choose proper libraries depending on float format. 41/* Choose proper libraries depending on float format.
42 Note that there are no profiling libraries for g-format. 42 Note that there are no profiling libraries for g-format.
43 Also use -lg for the sake of dbx. */ 43 Also use -lg for the sake of dbx. */
44 44
45#define LIB_SPEC "%{g:-lg}\ 45#define LIB_SPEC "%{g:-lg}\
46 %{mg:%{lm:-lmg} -lcg \ 46 %{mg:%{lm:-lmg} -lcg \
47 %{p:%eprofiling not supported with -mg\n}\ 47 %{p:%eprofiling not supported with -mg\n}\
48 %{pg:%eprofiling not supported with -mg\n}}\ 48 %{pg:%eprofiling not supported with -mg\n}}\
49 %{!mg:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}" 49 %{!mg:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
50 50
51/* Run-time compilation parameters selecting different hardware subsets. */ 51/* Run-time compilation parameters selecting different hardware subsets. */
52 52
53/* Nonzero if ELF. Redefined by vax/elf.h. */ 53/* Nonzero if ELF. Redefined by vax/elf.h. */
54#define TARGET_ELF 0 54#define TARGET_ELF 0
55 55
56/* Use BSD names for udiv and umod libgcc calls. */ 56/* Use BSD names for udiv and umod libgcc calls. */
57#define TARGET_BSD_DIVMOD 1 57#define TARGET_BSD_DIVMOD 1
58 58
59/* Default target_flags if no switches specified. */ 59/* Default target_flags if no switches specified. */
60 60
61#ifndef TARGET_DEFAULT 61#ifndef TARGET_DEFAULT
62#define TARGET_DEFAULT (MASK_UNIX_ASM) 62#define TARGET_DEFAULT (MASK_UNIX_ASM)
63#endif 63#endif
64 64
65  65
66/* Target machine storage layout */ 66/* Target machine storage layout */
67 67
68/* Define this if most significant bit is lowest numbered 68/* Define this if most significant bit is lowest numbered
69 in instructions that operate on numbered bit-fields. 69 in instructions that operate on numbered bit-fields.
70 This is not true on the VAX. */ 70 This is not true on the VAX. */
71#define BITS_BIG_ENDIAN 0 71#define BITS_BIG_ENDIAN 0
72 72
73/* Define this if most significant byte of a word is the lowest numbered. */ 73/* Define this if most significant byte of a word is the lowest numbered. */
74/* That is not true on the VAX. */ 74/* That is not true on the VAX. */
75#define BYTES_BIG_ENDIAN 0 75#define BYTES_BIG_ENDIAN 0
76 76
77/* Define this if most significant word of a multiword number is the lowest 77/* Define this if most significant word of a multiword number is the lowest
78 numbered. */ 78 numbered. */
79/* This is not true on the VAX. */ 79/* This is not true on the VAX. */
80#define WORDS_BIG_ENDIAN 0 80#define WORDS_BIG_ENDIAN 0
81 81
82/* Width of a word, in units (bytes). */ 82/* Width of a word, in units (bytes). */
83#define UNITS_PER_WORD 4 83#define UNITS_PER_WORD 4
84 84
85/* Allocation boundary (in *bits*) for storing arguments in argument list. */ 85/* Allocation boundary (in *bits*) for storing arguments in argument list. */
86#define PARM_BOUNDARY 32 86#define PARM_BOUNDARY 32
87 87
88/* Allocation boundary (in *bits*) for the code of a function. */ 88/* Allocation boundary (in *bits*) for the code of a function. */
89#define FUNCTION_BOUNDARY 16 89#define FUNCTION_BOUNDARY 16
90 90
91/* Alignment of field after `int : 0' in a structure. */ 91/* Alignment of field after `int : 0' in a structure. */
92#define EMPTY_FIELD_BOUNDARY (TARGET_VAXC_ALIGNMENT ? 8 : 32) 92#define EMPTY_FIELD_BOUNDARY (TARGET_VAXC_ALIGNMENT ? 8 : 32)
93 93
94/* Every structure's size must be a multiple of this. */ 94/* Every structure's size must be a multiple of this. */
95#define STRUCTURE_SIZE_BOUNDARY 8 95#define STRUCTURE_SIZE_BOUNDARY 8
96 96
97/* A bit-field declared as `int' forces `int' alignment for the struct. */ 97/* A bit-field declared as `int' forces `int' alignment for the struct. */
98#define PCC_BITFIELD_TYPE_MATTERS (! TARGET_VAXC_ALIGNMENT) 98#define PCC_BITFIELD_TYPE_MATTERS (! TARGET_VAXC_ALIGNMENT)
99 99
100/* No data type wants to be aligned rounder than this. */ 100/* No data type wants to be aligned rounder than this. */
101#define BIGGEST_ALIGNMENT 32 101#define BIGGEST_ALIGNMENT 32
102 102
103/* No structure field wants to be aligned rounder than this. */ 103/* No structure field wants to be aligned rounder than this. */
104#define BIGGEST_FIELD_ALIGNMENT (TARGET_VAXC_ALIGNMENT ? 8 : 32) 104#define BIGGEST_FIELD_ALIGNMENT (TARGET_VAXC_ALIGNMENT ? 8 : 32)
105 105
106/* Set this nonzero if move instructions will actually fail to work 106/* Set this nonzero if move instructions will actually fail to work
107 when given unaligned data. */ 107 when given unaligned data. */
108#define STRICT_ALIGNMENT 0 108#define STRICT_ALIGNMENT 0
109 109
110/* Let's keep the stack somewhat aligned. */ 110/* Let's keep the stack somewhat aligned. */
111#define STACK_BOUNDARY 32 111#define STACK_BOUNDARY 32
112 112
113/* The table of an ADDR_DIFF_VEC must be contiguous with the case 113/* The table of an ADDR_DIFF_VEC must be contiguous with the case
114 opcode, it is part of the case instruction. */ 114 opcode, it is part of the case instruction. */
115#define ADDR_VEC_ALIGN(ADDR_VEC) 0 115#define ADDR_VEC_ALIGN(ADDR_VEC) 0
116  116
117/* Standard register usage. */ 117/* Standard register usage. */
118 118
119/* Number of actual hardware registers. 119/* Number of actual hardware registers.
120 The hardware registers are assigned numbers for the compiler 120 The hardware registers are assigned numbers for the compiler
121 from 0 to just below FIRST_PSEUDO_REGISTER. 121 from 0 to just below FIRST_PSEUDO_REGISTER.
122 All registers that the compiler knows about must be given numbers, 122 All registers that the compiler knows about must be given numbers,
123 even those that are not normally considered general registers. */ 123 even those that are not normally considered general registers. */
124#define FIRST_PSEUDO_REGISTER 16 124#define FIRST_PSEUDO_REGISTER 16
125 125
126/* 1 for registers that have pervasive standard uses 126/* 1 for registers that have pervasive standard uses
127 and are not available for the register allocator. 127 and are not available for the register allocator.
128 On the VAX, these are the AP, FP, SP and PC. */ 128 On the VAX, these are the AP, FP, SP and PC. */
129#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} 129#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
130 130
131/* 1 for registers not available across function calls. 131/* 1 for registers not available across function calls.
132 These must include the FIXED_REGISTERS and also any 132 These must include the FIXED_REGISTERS and also any
133 registers that can be used without being saved. 133 registers that can be used without being saved.
134 The latter must include the registers where values are returned 134 The latter must include the registers where values are returned
135 and the register where structure-value addresses are passed. 135 and the register where structure-value addresses are passed.
136 Aside from that, you can include as many other registers as you like. */ 136 Aside from that, you can include as many other registers as you like. */
137#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} 137#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
138 138
139/* Return number of consecutive hard regs needed starting at reg REGNO 139/* Return number of consecutive hard regs needed starting at reg REGNO
140 to hold something of mode MODE. 140 to hold something of mode MODE.
141 This is ordinarily the length in words of a value of mode MODE 141 This is ordinarily the length in words of a value of mode MODE
142 but can be less for certain modes in special long registers. 142 but can be less for certain modes in special long registers.
143 On the VAX, all registers are one word long. */ 143 On the VAX, all registers are one word long. */
144#define HARD_REGNO_NREGS(REGNO, MODE) \ 144#define HARD_REGNO_NREGS(REGNO, MODE) \
145 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) 145 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
146 146
147/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. 147/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
148 On the VAX, all registers can hold all modes. */ 148 On the VAX, all registers can hold all modes. */
149#define HARD_REGNO_MODE_OK(REGNO, MODE) 1 149#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
150 150
151/* Value is 1 if it is a good idea to tie two pseudo registers 151/* Value is 1 if it is a good idea to tie two pseudo registers
152 when one has mode MODE1 and one has mode MODE2. 152 when one has mode MODE1 and one has mode MODE2.
153 If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, 153 If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
154 for any hard reg, then this must be 0 for correct output. */ 154 for any hard reg, then this must be 0 for correct output. */
155#define MODES_TIEABLE_P(MODE1, MODE2) 1 155#define MODES_TIEABLE_P(MODE1, MODE2) 1
156 156
157/* Specify the registers used for certain standard purposes. 157/* Specify the registers used for certain standard purposes.
158 The values of these macros are register numbers. */ 158 The values of these macros are register numbers. */
159 159
160/* VAX PSW for DWARF-2 */ 160/* VAX PSW for DWARF-2 */
161#define PSW_REGNUM VAX_PSW_REGNUM 161#define PSW_REGNUM VAX_PSW_REGNUM
162 162
163/* VAX pc is overloaded on a register. */ 163/* VAX pc is overloaded on a register. */
164#define PC_REGNUM VAX_PC_REGNUM 164#define PC_REGNUM VAX_PC_REGNUM
165 165
166/* Register to use for pushing function arguments. */ 166/* Register to use for pushing function arguments. */
167#define STACK_POINTER_REGNUM VAX_SP_REGNUM 167#define STACK_POINTER_REGNUM VAX_SP_REGNUM
168 168
169/* Base register for access to local variables of the function. */ 169/* Base register for access to local variables of the function. */
170#define FRAME_POINTER_REGNUM VAX_FP_REGNUM 170#define FRAME_POINTER_REGNUM VAX_FP_REGNUM
171 171
172/* Offset from the frame pointer register value to the top of stack. */ 
173#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0 
174 
175/* Base register for access to arguments of the function. */ 172/* Base register for access to arguments of the function. */
176#define ARG_POINTER_REGNUM VAX_AP_REGNUM 173#define ARG_POINTER_REGNUM VAX_AP_REGNUM
177 174
 175/* Offset from the argument pointer register value to the CFA. */
 176#define ARG_POINTER_CFA_OFFSET(FNDECL) 0
 177
178/* Register in which static-chain is passed to a function. */ 178/* Register in which static-chain is passed to a function. */
179#define STATIC_CHAIN_REGNUM 0 179#define STATIC_CHAIN_REGNUM 0
180 180
181/* Register in which address to store a structure value 181/* Register in which address to store a structure value
182 is passed to a function. */ 182 is passed to a function. */
183#define VAX_STRUCT_VALUE_REGNUM 1 183#define VAX_STRUCT_VALUE_REGNUM 1
184  184
185/* Define the classes of registers for register constraints in the 185/* Define the classes of registers for register constraints in the
186 machine description. Also define ranges of constants. 186 machine description. Also define ranges of constants.
187 187
188 One of the classes must always be named ALL_REGS and include all hard regs. 188 One of the classes must always be named ALL_REGS and include all hard regs.
189 If there is more than one class, another class must be named NO_REGS 189 If there is more than one class, another class must be named NO_REGS
190 and contain no registers. 190 and contain no registers.
191 191
192 The name GENERAL_REGS must be the name of a class (or an alias for 192 The name GENERAL_REGS must be the name of a class (or an alias for
193 another name such as ALL_REGS). This is the class of registers 193 another name such as ALL_REGS). This is the class of registers
194 that is allowed by "g" or "r" in a register constraint. 194 that is allowed by "g" or "r" in a register constraint.
195 Also, registers outside this class are allocated only when 195 Also, registers outside this class are allocated only when
196 instructions express preferences for them. 196 instructions express preferences for them.
197 197
198 The classes must be numbered in nondecreasing order; that is, 198 The classes must be numbered in nondecreasing order; that is,
199 a larger-numbered class must never be contained completely 199 a larger-numbered class must never be contained completely
200 in a smaller-numbered class. 200 in a smaller-numbered class.
201 201
202 For any two classes, it is very desirable that there be another 202 For any two classes, it is very desirable that there be another
203 class that represents their union. */ 203 class that represents their union. */
204 204
205/* The VAX has only one kind of registers, so NO_REGS and ALL_REGS 205/* The VAX has only one kind of registers, so NO_REGS and ALL_REGS
206 are the only classes. */ 206 are the only classes. */
207 207
208enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; 208enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
209 209
210#define N_REG_CLASSES (int) LIM_REG_CLASSES 210#define N_REG_CLASSES (int) LIM_REG_CLASSES
211 211
212/* Since GENERAL_REGS is the same class as ALL_REGS, 212/* Since GENERAL_REGS is the same class as ALL_REGS,
213 don't give it a different class number; just make it an alias. */ 213 don't give it a different class number; just make it an alias. */
214 214
215#define GENERAL_REGS ALL_REGS 215#define GENERAL_REGS ALL_REGS
216 216
217/* Give names of register classes as strings for dump file. */ 217/* Give names of register classes as strings for dump file. */
218 218
219#define REG_CLASS_NAMES \ 219#define REG_CLASS_NAMES \
220 { "NO_REGS", "ALL_REGS" } 220 { "NO_REGS", "ALL_REGS" }
221 221
222/* Define which registers fit in which classes. 222/* Define which registers fit in which classes.
223 This is an initializer for a vector of HARD_REG_SET 223 This is an initializer for a vector of HARD_REG_SET
224 of length N_REG_CLASSES. */ 224 of length N_REG_CLASSES. */
225 225
226#define REG_CLASS_CONTENTS {{0}, {0xffff}} 226#define REG_CLASS_CONTENTS {{0}, {0xffff}}
227 227
228/* The same information, inverted: 228/* The same information, inverted:
229 Return the class number of the smallest class containing 229 Return the class number of the smallest class containing
230 reg number REGNO. This could be a conditional expression 230 reg number REGNO. This could be a conditional expression
231 or could index an array. */ 231 or could index an array. */
232 232
233#define REGNO_REG_CLASS(REGNO) ALL_REGS 233#define REGNO_REG_CLASS(REGNO) ALL_REGS
234 234
235/* The class value for index registers, and the one for base regs. */ 235/* The class value for index registers, and the one for base regs. */
236 236
237#define INDEX_REG_CLASS ALL_REGS 237#define INDEX_REG_CLASS ALL_REGS
238#define BASE_REG_CLASS ALL_REGS 238#define BASE_REG_CLASS ALL_REGS
239 239
240  240
241/* Stack layout; function entry, exit and calling. */ 241/* Stack layout; function entry, exit and calling. */
242 242
243/* Define this if pushing a word on the stack 243/* Define this if pushing a word on the stack
244 makes the stack pointer a smaller address. */ 244 makes the stack pointer a smaller address. */
245#define STACK_GROWS_DOWNWARD 245#define STACK_GROWS_DOWNWARD
246 246
247/* Define this to nonzero if the nominal address of the stack frame 247/* Define this to nonzero if the nominal address of the stack frame
248 is at the high-address end of the local variables; 248 is at the high-address end of the local variables;
249 that is, each additional local variable allocated 249 that is, each additional local variable allocated
250 goes at a more negative offset in the frame. */ 250 goes at a more negative offset in the frame. */
251#define FRAME_GROWS_DOWNWARD 1 251#define FRAME_GROWS_DOWNWARD 1
252 252
253/* Offset within stack frame to start allocating local variables at. 253/* Offset within stack frame to start allocating local variables at.
254 If FRAME_GROWS_DOWNWARD, this is the offset to the END of the 254 If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
255 first local allocated. Otherwise, it is the offset to the BEGINNING 255 first local allocated. Otherwise, it is the offset to the BEGINNING
256 of the first local allocated. */ 256 of the first local allocated. */
257#define STARTING_FRAME_OFFSET 0 257#define STARTING_FRAME_OFFSET 0
258 258
259/* Given an rtx for the address of a frame, 259/* Given an rtx for the address of a frame,
260 return an rtx for the address of the word in the frame 260 return an rtx for the address of the word in the frame
261 that holds the dynamic chain--the previous frame's address. */ 261 that holds the dynamic chain--the previous frame's address. */
262#define DYNAMIC_CHAIN_ADDRESS(FRAME) plus_constant (Pmode, (FRAME), 12) 262#define DYNAMIC_CHAIN_ADDRESS(FRAME) plus_constant (Pmode, (FRAME), 12)
263 263
264/* If we generate an insn to push BYTES bytes, 264/* If we generate an insn to push BYTES bytes,
265 this says how many the stack pointer really advances by. 265 this says how many the stack pointer really advances by.
266 On the VAX, -(sp) pushes only the bytes of the operands. */ 266 On the VAX, -(sp) pushes only the bytes of the operands. */
267#define PUSH_ROUNDING(BYTES) (BYTES) 267#define PUSH_ROUNDING(BYTES) (BYTES)
268 268
269/* Offset of first parameter from the argument pointer register value. */ 269/* Offset of first parameter from the argument pointer register value. */
270#define FIRST_PARM_OFFSET(FNDECL) 4 270#define FIRST_PARM_OFFSET(FNDECL) 4
271 271
272/* Define how to find the value returned by a function. 272/* Define how to find the value returned by a function.
273 VALTYPE is the data type of the value (as a tree). 273 VALTYPE is the data type of the value (as a tree).
274 If the precise function being called is known, FUNC is its FUNCTION_DECL; 274 If the precise function being called is known, FUNC is its FUNCTION_DECL;
275 otherwise, FUNC is 0. */ 275 otherwise, FUNC is 0. */
276 276
277/* On the VAX the return value is in R0 regardless. */ 277/* On the VAX the return value is in R0 regardless. */
278 278
279#define FUNCTION_VALUE(VALTYPE, FUNC) \ 279#define FUNCTION_VALUE(VALTYPE, FUNC) \
280 gen_rtx_REG (TYPE_MODE (VALTYPE), 0) 280 gen_rtx_REG (TYPE_MODE (VALTYPE), 0)
281 281
282/* Define how to find the value returned by a library function 282/* Define how to find the value returned by a library function
283 assuming the value has mode MODE. */ 283 assuming the value has mode MODE. */
284 284
285/* On the VAX the return value is in R0 regardless. */ 285/* On the VAX the return value is in R0 regardless. */
286 286
287#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, 0) 287#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, 0)
288 288
289/* Define this if PCC uses the nonreentrant convention for returning 289/* Define this if PCC uses the nonreentrant convention for returning
290 structure and union values. */ 290 structure and union values. */
291 291
292#define PCC_STATIC_STRUCT_RETURN 292#define PCC_STATIC_STRUCT_RETURN
293 293
294/* 1 if N is a possible register number for a function value. 294/* 1 if N is a possible register number for a function value.
295 On the VAX, R0 is the only register thus used. */ 295 On the VAX, R0 is the only register thus used. */
296 296
297#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0) 297#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
298 298
299/* 1 if N is a possible register number for function argument passing. 299/* 1 if N is a possible register number for function argument passing.
300 On the VAX, no registers are used in this way. */ 300 On the VAX, no registers are used in this way. */
301 301
302#define FUNCTION_ARG_REGNO_P(N) ((void) (N), 0) 302#define FUNCTION_ARG_REGNO_P(N) ((void) (N), 0)
303  303
304/* Define a data type for recording info about an argument list 304/* Define a data type for recording info about an argument list
305 during the scan of that argument list. This data type should 305 during the scan of that argument list. This data type should
306 hold all necessary information about the function itself 306 hold all necessary information about the function itself
307 and about the args processed so far, enough to enable macros 307 and about the args processed so far, enough to enable macros
308 such as FUNCTION_ARG to determine where the next arg should go. 308 such as FUNCTION_ARG to determine where the next arg should go.
309 309
310 On the VAX, this is a single integer, which is a number of bytes 310 On the VAX, this is a single integer, which is a number of bytes
311 of arguments scanned so far. */ 311 of arguments scanned so far. */
312 312
313#define CUMULATIVE_ARGS int 313#define CUMULATIVE_ARGS int
314 314
315/* Initialize a variable CUM of type CUMULATIVE_ARGS 315/* Initialize a variable CUM of type CUMULATIVE_ARGS
316 for a call to a function whose data type is FNTYPE. 316 for a call to a function whose data type is FNTYPE.
317 For a library call, FNTYPE is 0. 317 For a library call, FNTYPE is 0.
318 318
319 On the VAX, the offset starts at 0. */ 319 On the VAX, the offset starts at 0. */
320 320
321#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ 321#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
322 ((CUM) = 0) 322 ((CUM) = 0)
323 323
324/* Output assembler code to FILE to increment profiler label # LABELNO 324/* Output assembler code to FILE to increment profiler label # LABELNO
325 for profiling a function entry. */ 325 for profiling a function entry. */
326 326
327#define VAX_FUNCTION_PROFILER_NAME "mcount" 327#define VAX_FUNCTION_PROFILER_NAME "mcount"
328#define FUNCTION_PROFILER(FILE, LABELNO) \ 328#define FUNCTION_PROFILER(FILE, LABELNO) \
329 do \ 329 do \
330 { \ 330 { \
331 char label[256]; \ 331 char label[256]; \
332 ASM_GENERATE_INTERNAL_LABEL (label, "LP", (LABELNO)); \ 332 ASM_GENERATE_INTERNAL_LABEL (label, "LP", (LABELNO)); \
333 fprintf (FILE, "\tmovab "); \ 333 fprintf (FILE, "\tmovab "); \
334 assemble_name (FILE, label); \ 334 assemble_name (FILE, label); \
335 asm_fprintf (FILE, ",%Rr0\n\tjsb %s\n", \ 335 asm_fprintf (FILE, ",%Rr0\n\tjsb %s\n", \
336 VAX_FUNCTION_PROFILER_NAME); \ 336 VAX_FUNCTION_PROFILER_NAME); \
337 } \ 337 } \
338 while (0) 338 while (0)
339 339
340/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, 340/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
341 the stack pointer does not matter. The value is tested only in 341 the stack pointer does not matter. The value is tested only in
342 functions that have frame pointers. 342 functions that have frame pointers.
343 No definition is equivalent to always zero. */ 343 No definition is equivalent to always zero. */
344 344
345#define EXIT_IGNORE_STACK 1 345#define EXIT_IGNORE_STACK 1
346 346
347/* Store in the variable DEPTH the initial difference between the 347/* Store in the variable DEPTH the initial difference between the
348 frame pointer reg contents and the stack pointer reg contents, 348 frame pointer reg contents and the stack pointer reg contents,
349 as of the start of the function body. This depends on the layout 349 as of the start of the function body. This depends on the layout
350 of the fixed parts of the stack frame and on how registers are saved. 350 of the fixed parts of the stack frame and on how registers are saved.
351 351
352 On the VAX, FRAME_POINTER_REQUIRED is always 1, so the definition of this 352 On the VAX, FRAME_POINTER_REQUIRED is always 1, so the definition of this
353 macro doesn't matter. But it must be defined. */ 353 macro doesn't matter. But it must be defined. */
354 354
355#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0; 355#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0;
356 356
357/* Length in units of the trampoline for entering a nested function. */ 357/* Length in units of the trampoline for entering a nested function. */
358 358
359#define TRAMPOLINE_SIZE 15 359#define TRAMPOLINE_SIZE 15
360 360
361/* Byte offset of return address in a stack frame. The "saved PC" field 361/* Byte offset of return address in a stack frame. The "saved PC" field
362 is in element [4] when treating the frame as an array of longwords. */ 362 is in element [4] when treating the frame as an array of longwords. */
363 363
364#define RETURN_ADDRESS_OFFSET (4 * UNITS_PER_WORD) /* 16 */ 364#define RETURN_ADDRESS_OFFSET (4 * UNITS_PER_WORD) /* 16 */
365 365
366/* A C expression whose value is RTL representing the value of the return 366/* A C expression whose value is RTL representing the value of the return
367 address for the frame COUNT steps up from the current frame. 367 address for the frame COUNT steps up from the current frame.
368 FRAMEADDR is already the frame pointer of the COUNT frame, so we 368 FRAMEADDR is already the frame pointer of the COUNT frame, so we
369 can ignore COUNT. */ 369 can ignore COUNT. */
370 370
371#define RETURN_ADDR_RTX(COUNT, FRAME) \ 371#define RETURN_ADDR_RTX(COUNT, FRAME) \
372 ((COUNT == 0) \ 372 ((COUNT == 0) \
373 ? gen_rtx_MEM (Pmode, plus_constant (Pmode, FRAME, \ 373 ? gen_rtx_MEM (Pmode, plus_constant (Pmode, FRAME, \
374 RETURN_ADDRESS_OFFSET)) \ 374 RETURN_ADDRESS_OFFSET)) \
375 : (rtx) 0) 375 : (rtx) 0)
376 376
377/* A C expression that is nonzero if X is a legitimate immediate operand 377/* A C expression that is nonzero if X is a legitimate immediate operand
378 on the target machine when generating position independent code. */ 378 on the target machine when generating position independent code. */
379 379
380#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X) 380#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
381  381
382/* Addressing modes, and classification of registers for them. */ 382/* Addressing modes, and classification of registers for them. */
383 383
384#define HAVE_POST_INCREMENT 1 384#define HAVE_POST_INCREMENT 1
385 385
386#define HAVE_PRE_DECREMENT 1 386#define HAVE_PRE_DECREMENT 1
387 387
388/* Macros to check register numbers against specific register classes. */ 388/* Macros to check register numbers against specific register classes. */
389 389
390/* These assume that REGNO is a hard or pseudo reg number. 390/* These assume that REGNO is a hard or pseudo reg number.
391 They give nonzero only if REGNO is a hard reg of the suitable class 391 They give nonzero only if REGNO is a hard reg of the suitable class
392 or a pseudo reg currently allocated to a suitable hard reg. 392 or a pseudo reg currently allocated to a suitable hard reg.
393 Since they use reg_renumber, they are safe only once reg_renumber 393 Since they use reg_renumber, they are safe only once reg_renumber
394 has been allocated, which happens in reginfo.c during register 394 has been allocated, which happens in reginfo.c during register
395 allocation. */ 395 allocation. */
396 396
397#define REGNO_OK_FOR_INDEX_P(regno) \ 397#define REGNO_OK_FOR_INDEX_P(regno) \
398 ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0) 398 ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
399#define REGNO_OK_FOR_BASE_P(regno) \ 399#define REGNO_OK_FOR_BASE_P(regno) \
400 ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0) 400 ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
401  401
402/* Maximum number of registers that can appear in a valid memory address. */ 402/* Maximum number of registers that can appear in a valid memory address. */
403 403
404#define MAX_REGS_PER_ADDRESS 2 404#define MAX_REGS_PER_ADDRESS 2
405 405
406/* 1 if X is an rtx for a constant that is a valid address. */ 406/* 1 if X is an rtx for a constant that is a valid address. */
407 407
408#define CONSTANT_ADDRESS_P(X) legitimate_constant_address_p (X) 408#define CONSTANT_ADDRESS_P(X) legitimate_constant_address_p (X)
409 409
410/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx 410/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
411 and check its validity for a certain class. 411 and check its validity for a certain class.
412 We have two alternate definitions for each of them. 412 We have two alternate definitions for each of them.
413 The usual definition accepts all pseudo regs; the other rejects 413 The usual definition accepts all pseudo regs; the other rejects
414 them unless they have been allocated suitable hard regs. 414 them unless they have been allocated suitable hard regs.
415 The symbol REG_OK_STRICT causes the latter definition to be used. 415 The symbol REG_OK_STRICT causes the latter definition to be used.
416 416
417 Most source files want to accept pseudo regs in the hope that 417 Most source files want to accept pseudo regs in the hope that
418 they will get allocated to the class that the insn wants them to be in. 418 they will get allocated to the class that the insn wants them to be in.
419 Source files for reload pass need to be strict. 419 Source files for reload pass need to be strict.
420 After reload, it makes no difference, since pseudo regs have 420 After reload, it makes no difference, since pseudo regs have
421 been eliminated by then. */ 421 been eliminated by then. */
422 422
423#ifndef REG_OK_STRICT 423#ifndef REG_OK_STRICT
424 424
425/* Nonzero if X is a hard reg that can be used as an index 425/* Nonzero if X is a hard reg that can be used as an index
426 or if it is a pseudo reg. */ 426 or if it is a pseudo reg. */
427#define REG_OK_FOR_INDEX_P(X) 1 427#define REG_OK_FOR_INDEX_P(X) 1
428 428
429/* Nonzero if X is a hard reg that can be used as a base reg 429/* Nonzero if X is a hard reg that can be used as a base reg
430 or if it is a pseudo reg. */ 430 or if it is a pseudo reg. */
431#define REG_OK_FOR_BASE_P(X) 1 431#define REG_OK_FOR_BASE_P(X) 1
432 432
433#else 433#else
434 434
435/* Nonzero if X is a hard reg that can be used as an index. */ 435/* Nonzero if X is a hard reg that can be used as an index. */
436#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) 436#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
437 437
438/* Nonzero if X is a hard reg that can be used as a base reg. */ 438/* Nonzero if X is a hard reg that can be used as a base reg. */
439#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) 439#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
440 440
441#endif 441#endif
442  442
443/* Specify the machine mode that this machine uses 443/* Specify the machine mode that this machine uses
444 for the index in the tablejump instruction. */ 444 for the index in the tablejump instruction. */
445#define CASE_VECTOR_MODE HImode 445#define CASE_VECTOR_MODE HImode
446 446
447/* Define as C expression which evaluates to nonzero if the tablejump 447/* Define as C expression which evaluates to nonzero if the tablejump
448 instruction expects the table to contain offsets from the address of the 448 instruction expects the table to contain offsets from the address of the
449 table. 449 table.
450 Do not define this if the table should contain absolute addresses. */ 450 Do not define this if the table should contain absolute addresses. */
451#define CASE_VECTOR_PC_RELATIVE 1 451#define CASE_VECTOR_PC_RELATIVE 1
452 452
453/* Indicate that jump tables go in the text section. This is 453/* Indicate that jump tables go in the text section. This is
454 necessary when compiling PIC code. */ 454 necessary when compiling PIC code. */
455#define JUMP_TABLES_IN_TEXT_SECTION 1 455#define JUMP_TABLES_IN_TEXT_SECTION 1
456 456
457/* Define this as 1 if `char' should by default be signed; else as 0. */ 457/* Define this as 1 if `char' should by default be signed; else as 0. */
458#define DEFAULT_SIGNED_CHAR 1 458#define DEFAULT_SIGNED_CHAR 1
459 459
460/* Max number of bytes we can move from memory to memory 460/* Max number of bytes we can move from memory to memory
461 in one reasonably fast instruction. */ 461 in one reasonably fast instruction. */
462#define MOVE_MAX 8 462#define MOVE_MAX 8
463 463
464/* If a memory-to-memory move would take MOVE_RATIO or more simple 464/* If a memory-to-memory move would take MOVE_RATIO or more simple
465 move-instruction pairs, we will do a movmem or libcall instead. */ 465 move-instruction pairs, we will do a movmem or libcall instead. */
466#define MOVE_RATIO(speed) ((speed) ? 6 : 3) 466#define MOVE_RATIO(speed) ((speed) ? 6 : 3)
467#define CLEAR_RATIO(speed) ((speed) ? 6 : 2) 467#define CLEAR_RATIO(speed) ((speed) ? 6 : 2)
468 468
469/* Nonzero if access to memory by bytes is slow and undesirable. */ 469/* Nonzero if access to memory by bytes is slow and undesirable. */
470#define SLOW_BYTE_ACCESS 0 470#define SLOW_BYTE_ACCESS 0
471 471
472/* Define if shifts truncate the shift count 472/* Define if shifts truncate the shift count
473 which implies one can omit a sign-extension or zero-extension 473 which implies one can omit a sign-extension or zero-extension
474 of a shift count. */ 474 of a shift count. */
475/* #define SHIFT_COUNT_TRUNCATED */ 475/* #define SHIFT_COUNT_TRUNCATED */
476 476
477/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits 477/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
478 is done just by pretending it is already truncated. */ 478 is done just by pretending it is already truncated. */
479#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 479#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
480 480
481/* Specify the machine mode that pointers have. 481/* Specify the machine mode that pointers have.
482 After generation of rtl, the compiler makes no further distinction 482 After generation of rtl, the compiler makes no further distinction
483 between pointers and any other objects of this machine mode. */ 483 between pointers and any other objects of this machine mode. */
484#define Pmode SImode 484#define Pmode SImode
485 485
486/* A function address in a call instruction 486/* A function address in a call instruction
487 is a byte address (for indexing purposes) 487 is a byte address (for indexing purposes)
488 so give the MEM rtx a byte's mode. */ 488 so give the MEM rtx a byte's mode. */
489#define FUNCTION_MODE QImode 489#define FUNCTION_MODE QImode
490 490
491/* Specify the cost of a branch insn; roughly the number of extra insns that 491/* Specify the cost of a branch insn; roughly the number of extra insns that
492 should be added to avoid a branch. 492 should be added to avoid a branch.
493 493
494 Branches are extremely cheap on the VAX while the shift insns often 494 Branches are extremely cheap on the VAX while the shift insns often
495 used to replace branches can be expensive. */ 495 used to replace branches can be expensive. */
496 496
497#define BRANCH_COST(speed_p, predictable_p) 0 497#define BRANCH_COST(speed_p, predictable_p) 0
498  498
499/* Tell final.c how to eliminate redundant test instructions. */ 499/* Tell final.c how to eliminate redundant test instructions. */
500 500
501/* Here we define machine-dependent flags and fields in cc_status 501/* Here we define machine-dependent flags and fields in cc_status
502 (see `conditions.h'). No extra ones are needed for the VAX. */ 502 (see `conditions.h'). No extra ones are needed for the VAX. */
503 503
504/* Store in cc_status the expressions 504/* Store in cc_status the expressions
505 that the condition codes will describe 505 that the condition codes will describe
506 after execution of an instruction whose pattern is EXP. 506 after execution of an instruction whose pattern is EXP.
507 Do not alter them if the instruction would not alter the cc's. */ 507 Do not alter them if the instruction would not alter the cc's. */
508 508
509#define NOTICE_UPDATE_CC(EXP, INSN) \ 509#define NOTICE_UPDATE_CC(EXP, INSN) \
510 vax_notice_update_cc ((EXP), (INSN)) 510 vax_notice_update_cc ((EXP), (INSN))
511 511
512#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ 512#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \
513 { if (cc_status.flags & CC_NO_OVERFLOW) \ 513 { if (cc_status.flags & CC_NO_OVERFLOW) \
514 return NO_OV; \ 514 return NO_OV; \
515 return NORMAL; \ 515 return NORMAL; \
516 } 516 }
517  517
518/* Control the assembler format that we output. */ 518/* Control the assembler format that we output. */
519 519
520/* A C string constant describing how to begin a comment in the target 520/* A C string constant describing how to begin a comment in the target
521 assembler language. The compiler assumes that the comment will end at 521 assembler language. The compiler assumes that the comment will end at
522 the end of the line. */ 522 the end of the line. */
523 523
524#define ASM_COMMENT_START "#" 524#define ASM_COMMENT_START "#"
525 525
526/* Output to assembler file text saying following lines 526/* Output to assembler file text saying following lines
527 may contain character constants, extra white space, comments, etc. */ 527 may contain character constants, extra white space, comments, etc. */
528 528
529#define ASM_APP_ON "#APP\n" 529#define ASM_APP_ON "#APP\n"
530 530
531/* Output to assembler file text saying following lines 531/* Output to assembler file text saying following lines
532 no longer contain unusual constructs. */ 532 no longer contain unusual constructs. */
533 533
534#define ASM_APP_OFF "#NO_APP\n" 534#define ASM_APP_OFF "#NO_APP\n"
535 535
536/* Output before read-only data. */ 536/* Output before read-only data. */
537 537
538#define TEXT_SECTION_ASM_OP "\t.text" 538#define TEXT_SECTION_ASM_OP "\t.text"
539 539
540/* Output before writable data. */ 540/* Output before writable data. */
541 541
542#define DATA_SECTION_ASM_OP "\t.data" 542#define DATA_SECTION_ASM_OP "\t.data"
543 543
544/* How to refer to registers in assembler output. 544/* How to refer to registers in assembler output.
545 This sequence is indexed by compiler's hard-register-number (see above). 545 This sequence is indexed by compiler's hard-register-number (see above).
546 The register names will be prefixed by REGISTER_PREFIX, if any. */ 546 The register names will be prefixed by REGISTER_PREFIX, if any. */
547 547
548#define REGISTER_PREFIX "" 548#define REGISTER_PREFIX ""
549#define REGISTER_NAMES \ 549#define REGISTER_NAMES \
550 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ 550 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
551 "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", } 551 "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", }
552 552
553/* This is BSD, so it wants DBX format. */ 553/* This is BSD, so it wants DBX format. */
554 554
555#define DBX_DEBUGGING_INFO 1 555#define DBX_DEBUGGING_INFO 1
556 556
557/* Do not break .stabs pseudos into continuations. */ 557/* Do not break .stabs pseudos into continuations. */
558 558
559#define DBX_CONTIN_LENGTH 0 559#define DBX_CONTIN_LENGTH 0
560 560
561/* This is the char to use for continuation (in case we need to turn 561/* This is the char to use for continuation (in case we need to turn
562 continuation back on). */ 562 continuation back on). */
563 563
564#define DBX_CONTIN_CHAR '?' 564#define DBX_CONTIN_CHAR '?'
565 565
566/* Don't use the `xsfoo;' construct in DBX output; this system 566/* Don't use the `xsfoo;' construct in DBX output; this system
567 doesn't support it. */ 567 doesn't support it. */
568 568
569#define DBX_NO_XREFS 569#define DBX_NO_XREFS
570 570
571/* Output the .stabs for a C `static' variable in the data section. */ 571/* Output the .stabs for a C `static' variable in the data section. */
572#define DBX_STATIC_STAB_DATA_SECTION 572#define DBX_STATIC_STAB_DATA_SECTION
573 573
574/* VAX specific: which type character is used for type double? */ 574/* VAX specific: which type character is used for type double? */
575 575
576#define ASM_DOUBLE_CHAR (TARGET_G_FLOAT ? 'g' : 'd') 576#define ASM_DOUBLE_CHAR (TARGET_G_FLOAT ? 'g' : 'd')
577 577
578/* This is how to output a command to make the user-level label named NAME 578/* This is how to output a command to make the user-level label named NAME
579 defined for reference from other files. */ 579 defined for reference from other files. */
580 580
581/* Globalizing directive for a label. */ 581/* Globalizing directive for a label. */
582#define GLOBAL_ASM_OP ".globl " 582#define GLOBAL_ASM_OP ".globl "
583 583
584/* The prefix to add to user-visible assembler symbols. */ 584/* The prefix to add to user-visible assembler symbols. */
585 585
586#define USER_LABEL_PREFIX "_" 586#define USER_LABEL_PREFIX "_"
587 587
588/* This is how to store into the string LABEL 588/* This is how to store into the string LABEL
589 the symbol_ref name of an internal numbered label where 589 the symbol_ref name of an internal numbered label where
590 PREFIX is the class of label and NUM is the number within the class. 590 PREFIX is the class of label and NUM is the number within the class.
591 This is suitable for output with `assemble_name'. */ 591 This is suitable for output with `assemble_name'. */
592 592
593#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ 593#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
594 sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM)) 594 sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM))
595 595
596/* This is how to output an insn to push a register on the stack. 596/* This is how to output an insn to push a register on the stack.
597 It need not be very fast code. */ 597 It need not be very fast code. */
598 598
599#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ 599#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
600 fprintf (FILE, "\tpushl %s\n", reg_names[REGNO]) 600 fprintf (FILE, "\tpushl %s\n", reg_names[REGNO])
601 601
602/* This is how to output an insn to pop a register from the stack. 602/* This is how to output an insn to pop a register from the stack.
603 It need not be very fast code. */ 603 It need not be very fast code. */
604 604
605#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ 605#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
606 fprintf (FILE, "\tmovl (%s)+,%s\n", reg_names[STACK_POINTER_REGNUM], \ 606 fprintf (FILE, "\tmovl (%s)+,%s\n", reg_names[STACK_POINTER_REGNUM], \
607 reg_names[REGNO]) 607 reg_names[REGNO])
608 608
609/* This is how to output an element of a case-vector that is absolute. 609/* This is how to output an element of a case-vector that is absolute.
610 (The VAX does not use such vectors, 610 (The VAX does not use such vectors,
611 but we must define this macro anyway.) */ 611 but we must define this macro anyway.) */
612 612
613#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ 613#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
614 do \ 614 do \
615 { \ 615 { \
616 char label[256]; \ 616 char label[256]; \
617 ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE));\ 617 ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE));\
618 fprintf (FILE, "\t.long "); \ 618 fprintf (FILE, "\t.long "); \
619 assemble_name (FILE, label); \ 619 assemble_name (FILE, label); \
620 fprintf (FILE, "\n"); \ 620 fprintf (FILE, "\n"); \
621 } \ 621 } \
622 while (0) 622 while (0)
623 623
624/* This is how to output an element of a case-vector that is relative. */ 624/* This is how to output an element of a case-vector that is relative. */
625 625
626#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ 626#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
627 do \ 627 do \
628 { \ 628 { \
629 char label[256]; \ 629 char label[256]; \
630 ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \ 630 ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \
631 fprintf (FILE, "\t.word "); \ 631 fprintf (FILE, "\t.word "); \
632 assemble_name (FILE, label); \ 632 assemble_name (FILE, label); \
633 ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL)); \ 633 ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL)); \
634 fprintf (FILE, "-"); \ 634 fprintf (FILE, "-"); \
635 assemble_name (FILE, label); \ 635 assemble_name (FILE, label); \
636 fprintf (FILE, "\n"); \ 636 fprintf (FILE, "\n"); \
637 } \ 637 } \
638 while (0) 638 while (0)
639 639
640/* This is how to output an assembler line 640/* This is how to output an assembler line
641 that says to advance the location counter 641 that says to advance the location counter
642 to a multiple of 2**LOG bytes. */ 642 to a multiple of 2**LOG bytes. */
643 643
644#define ASM_OUTPUT_ALIGN(FILE,LOG) \ 644#define ASM_OUTPUT_ALIGN(FILE,LOG) \
645 fprintf (FILE, "\t.align %d\n", (LOG)) 645 fprintf (FILE, "\t.align %d\n", (LOG))
646 646
647/* This is how to output an assembler line 647/* This is how to output an assembler line
648 that says to advance the location counter by SIZE bytes. */ 648 that says to advance the location counter by SIZE bytes. */
649 649
650#define ASM_OUTPUT_SKIP(FILE,SIZE) \ 650#define ASM_OUTPUT_SKIP(FILE,SIZE) \
651 fprintf (FILE, "\t.space %u\n", (int)(SIZE)) 651 fprintf (FILE, "\t.space %u\n", (int)(SIZE))
652 652
653/* This says how to output an assembler line 653/* This says how to output an assembler line
654 to define a global common symbol. */ 654 to define a global common symbol. */
655 655
656#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ 656#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
657 ( fputs (".comm ", (FILE)), \ 657 ( fputs (".comm ", (FILE)), \
658 assemble_name ((FILE), (NAME)), \ 658 assemble_name ((FILE), (NAME)), \
659 fprintf ((FILE), ",%u\n", (int)(ROUNDED))) 659 fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
660 660
661/* This says how to output an assembler line 661/* This says how to output an assembler line
662 to define a local common symbol. */ 662 to define a local common symbol. */
663 663
664#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ 664#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
665 ( fputs (".lcomm ", (FILE)), \ 665 ( fputs (".lcomm ", (FILE)), \
666 assemble_name ((FILE), (NAME)), \ 666 assemble_name ((FILE), (NAME)), \
667 fprintf ((FILE), ",%u\n", (int)(ROUNDED))) 667 fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
668 668
669/* Print an instruction operand X on file FILE. 669/* Print an instruction operand X on file FILE.
670 CODE is the code from the %-spec that requested printing this operand; 670 CODE is the code from the %-spec that requested printing this operand;
671 if `%z3' was used to print operand 3, then CODE is 'z'. 671 if `%z3' was used to print operand 3, then CODE is 'z'.
672 672
673VAX operand formatting codes: 673VAX operand formatting codes:
674 674
675 letter print 675 letter print
676 c direct branch condition 676 c direct branch condition
677 C reverse branch condition 677 C reverse branch condition
678 D 64-bit immediate operand 678 D 64-bit immediate operand
679 B the low 8 bits of the complement of a constant operand 679 B the low 8 bits of the complement of a constant operand
680 H the low 16 bits of the complement of a constant operand 680 H the low 16 bits of the complement of a constant operand
681 M a mask for the N highest bits of a word 681 M a mask for the N highest bits of a word
682 N the complement of a constant integer operand 682 N the complement of a constant integer operand
683 P constant operand plus 1 683 P constant operand plus 1
684 R 32 - constant operand 684 R 32 - constant operand
685 b the low 8 bits of a negated constant operand 685 b the low 8 bits of a negated constant operand
686 h the low 16 bits of a negated constant operand 686 h the low 16 bits of a negated constant operand
687 # 'd' or 'g' depending on whether dfloat or gfloat is used 687 # 'd' or 'g' depending on whether dfloat or gfloat is used
688 | register prefix */ 688 | register prefix */
689 689
690/* The purpose of D is to get around a quirk or bug in VAX assembler 690/* The purpose of D is to get around a quirk or bug in VAX assembler
691 whereby -1 in a 64-bit immediate operand means 0x00000000ffffffff, 691 whereby -1 in a 64-bit immediate operand means 0x00000000ffffffff,
692 which is not a 64-bit minus one. As a workaround, we output negative 692 which is not a 64-bit minus one. As a workaround, we output negative
693 values in hex. */ 693 values in hex. */
694#if HOST_BITS_PER_WIDE_INT == 64 694#if HOST_BITS_PER_WIDE_INT == 64
695# define NEG_HWI_PRINT_HEX16 HOST_WIDE_INT_PRINT_HEX 695# define NEG_HWI_PRINT_HEX16 HOST_WIDE_INT_PRINT_HEX
696#else 696#else
697# define NEG_HWI_PRINT_HEX16 "0xffffffff%08lx" 697# define NEG_HWI_PRINT_HEX16 "0xffffffff%08lx"
698#endif 698#endif
699 699
700#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ 700#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
701 ((CODE) == '#' || (CODE) == '|') 701 ((CODE) == '#' || (CODE) == '|')
702 702
703#define PRINT_OPERAND(FILE, X, CODE) \ 703#define PRINT_OPERAND(FILE, X, CODE) \
704 print_operand (FILE, X, CODE) 704 print_operand (FILE, X, CODE)
705 705
706/* Print a memory operand whose address is X, on file FILE. 706/* Print a memory operand whose address is X, on file FILE.
707 This uses a function in output-vax.c. */ 707 This uses a function in output-vax.c. */
708 708
709#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ 709#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
710 print_operand_address (FILE, ADDR) 710 print_operand_address (FILE, ADDR)
711 711
712/* This is a blatent lie. However, it's good enough, since we don't 712/* This is a blatent lie. However, it's good enough, since we don't
713 actually have any code whatsoever for which this isn't overridden 713 actually have any code whatsoever for which this isn't overridden
714 by the proper FDE definition. */ 714 by the proper FDE definition. */
715#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, PC_REGNUM) 715#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, PC_REGNUM)
716 716

cvs diff -r1.9 -r1.10 src/external/gpl3/gcc/dist/gcc/config/vax/vax.md (switch to unified diff)

--- src/external/gpl3/gcc/dist/gcc/config/vax/vax.md 2016/01/24 09:43:34 1.9
+++ src/external/gpl3/gcc/dist/gcc/config/vax/vax.md 2016/03/23 12:52:43 1.10
@@ -1,1728 +1,1700 @@ @@ -1,1728 +1,1700 @@
1;; Machine description for GNU compiler, VAX Version 1;; Machine description for GNU compiler, VAX Version
2;; Copyright (C) 1987-2015 Free Software Foundation, Inc. 2;; Copyright (C) 1987-2015 Free Software Foundation, Inc.
3 3
4;; This file is part of GCC. 4;; This file is part of GCC.
5 5
6;; GCC is free software; you can redistribute it and/or modify 6;; GCC is free software; you can redistribute it and/or modify
7;; it under the terms of the GNU General Public License as published by 7;; it under the terms of the GNU General Public License as published by
8;; the Free Software Foundation; either version 3, or (at your option) 8;; the Free Software Foundation; either version 3, or (at your option)
9;; any later version. 9;; any later version.
10 10
11;; GCC is distributed in the hope that it will be useful, 11;; GCC is distributed in the hope that it will be useful,
12;; but WITHOUT ANY WARRANTY; without even the implied warranty of 12;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;; GNU General Public License for more details. 14;; GNU General Public License for more details.
15 15
16;; You should have received a copy of the GNU General Public License 16;; You should have received a copy of the GNU General Public License
17;; along with GCC; see the file COPYING3. If not see 17;; along with GCC; see the file COPYING3. If not see
18;; <http://www.gnu.org/licenses/>. 18;; <http://www.gnu.org/licenses/>.
19 19
20 20
 21;; Note that operand 1 is total size of args, in bytes,
 22;; and what the call insn wants is the number of words.
 23;; It is used in the call instruction as a byte, but in the addl2 as
 24;; a word. Since the only time we actually use it in the call instruction
 25;; is when it is a constant, SImode (for addl2) is the proper mode.
21;;- Instruction patterns. When multiple patterns apply, 26;;- Instruction patterns. When multiple patterns apply,
22;;- the first one in the file is chosen. 27;;- the first one in the file is chosen.
23;;- 28;;-
24;;- See file "rtl.def" for documentation on define_insn, match_*, et al. 29;;- See file "rtl.def" for documentation on define_insn, match_*, et al.
25;;- 30;;-
26;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code 31;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
27;;- updates for most instructions. 32;;- updates for most instructions.
28 33
29;; UNSPEC_VOLATILE usage: 34;; UNSPEC_VOLATILE usage:
30 35
31(define_c_enum "unspecv" [ 36(define_c_enum "unspecv" [
32 VUNSPEC_BLOCKAGE ; 'blockage' insn to prevent scheduling across an 37 VUNSPEC_BLOCKAGE ; 'blockage' insn to prevent scheduling across an
33 ; insn in the code. 38 ; insn in the code.
34 VUNSPEC_SYNC_ISTREAM ; sequence of insns to sync the I-stream 39 VUNSPEC_SYNC_ISTREAM ; sequence of insns to sync the I-stream
35 VUNSPEC_PEM ; 'procedure_entry_mask' insn. 40 VUNSPEC_PEM ; 'procedure_entry_mask' insn.
36]) 41])
37 42
38(define_constants 43(define_constants
39 [(VAX_AP_REGNUM 12) ; Register 12 contains the argument pointer 44 [(VAX_AP_REGNUM 12) ; Register 12 contains the argument pointer
40 (VAX_FP_REGNUM 13) ; Register 13 contains the frame pointer 45 (VAX_FP_REGNUM 13) ; Register 13 contains the frame pointer
41 (VAX_SP_REGNUM 14) ; Register 14 contains the stack pointer 46 (VAX_SP_REGNUM 14) ; Register 14 contains the stack pointer
42 (VAX_PC_REGNUM 15) ; Register 15 contains the program counter 47 (VAX_PC_REGNUM 15) ; Register 15 contains the program counter
43 (VAX_PSW_REGNUM 16) ; Program Status Word 48 (VAX_PSW_REGNUM 16) ; Program Status Word
44 ] 49 ]
45) 50)
46 51
47;; Integer modes supported on VAX, with a mapping from machine mode 52;; Integer modes supported on VAX, with a mapping from machine mode
48;; to mnemonic suffix. DImode is always a special case. 53;; to mnemonic suffix. DImode is always a special case.
49(define_mode_iterator VAXint [QI HI SI]) 54(define_mode_iterator VAXint [QI HI SI])
50(define_mode_iterator VAXintQH [QI HI]) 55(define_mode_iterator VAXintQH [QI HI])
51(define_mode_iterator VAXintQHSD [QI HI SI DI]) 56(define_mode_iterator VAXintQHSD [QI HI SI DI])
52(define_mode_attr isfx [(QI "b") (HI "w") (SI "l") (DI "q")]) 57(define_mode_attr isfx [(QI "b") (HI "w") (SI "l") (DI "q")])
53 58
54;; Similar for float modes supported on VAX. 59;; Similar for float modes supported on VAX.
55(define_mode_iterator VAXfp [SF DF]) 60(define_mode_iterator VAXfp [SF DF])
56(define_mode_attr fsfx [(SF "f") (DF "%#")]) 61(define_mode_attr fsfx [(SF "f") (DF "%#")])
57 62
58;; Some output patterns want integer immediates with a prefix... 63;; Some output patterns want integer immediates with a prefix...
59(define_mode_attr iprefx [(QI "B") (HI "H") (SI "N")]) 64(define_mode_attr iprefx [(QI "B") (HI "H") (SI "N")])
60 65
61;; 66;;
62(include "constraints.md") 67(include "constraints.md")
63(include "predicates.md") 68(include "predicates.md")
64 69
65(define_insn "*cmp<mode>" 70(define_insn "*cmp<mode>"
66 [(set (cc0) 71 [(set (cc0)
67 (compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT") 72 (compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT")
68 (match_operand:VAXint 1 "general_operand" "I,nrmT")))] 73 (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
69 "" 74 ""
70 "@ 75 "@
71 tst<VAXint:isfx> %0 76 tst<VAXint:isfx> %0
72 cmp<VAXint:isfx> %0,%1") 77 cmp<VAXint:isfx> %0,%1")
73 78
74(define_insn "*cmp<mode>" 79(define_insn "*cmp<mode>"
75 [(set (cc0) 80 [(set (cc0)
76 (compare (match_operand:VAXfp 0 "general_operand" "gF,gF") 81 (compare (match_operand:VAXfp 0 "general_operand" "gF,gF")
77 (match_operand:VAXfp 1 "general_operand" "G,gF")))] 82 (match_operand:VAXfp 1 "general_operand" "G,gF")))]
78 "" 83 ""
79 "@ 84 "@
80 tst<VAXfp:fsfx> %0 85 tst<VAXfp:fsfx> %0
81 cmp<VAXfp:fsfx> %0,%1") 86 cmp<VAXfp:fsfx> %0,%1")
82 87
83(define_insn "*bit<mode>" 88(define_insn "*bit<mode>"
84 [(set (cc0) 89 [(set (cc0)
85 (compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT") 90 (compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
86 (match_operand:VAXint 1 "general_operand" "nrmT")) 91 (match_operand:VAXint 1 "general_operand" "nrmT"))
87 (const_int 0)))] 92 (const_int 0)))]
88 "" 93 ""
89 "bit<VAXint:isfx> %0,%1") 94 "bit<VAXint:isfx> %0,%1")
90 95
91;; The VAX has no sCOND insns. It does have add/subtract with carry 96;; The VAX has no sCOND insns. It does have add/subtract with carry
92;; which could be used to implement the sltu and sgeu patterns. However, 97;; which could be used to implement the sltu and sgeu patterns. However,
93;; to do this properly requires a complete rewrite of the compare insns 98;; to do this properly requires a complete rewrite of the compare insns
94;; to keep them together with the sltu/sgeu insns until after the 99;; to keep them together with the sltu/sgeu insns until after the
95;; reload pass is complete. The previous implementation didn't do this 100;; reload pass is complete. The previous implementation didn't do this
96;; and has been deleted. 101;; and has been deleted.
97 102
98  103
99(define_insn "mov<mode>" 104(define_insn "mov<mode>"
100 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") 105 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
101 (match_operand:VAXfp 1 "general_operand" "G,gF"))] 106 (match_operand:VAXfp 1 "general_operand" "G,gF"))]
102 "" 107 ""
103 "@ 108 "@
104 clr<VAXfp:fsfx> %0 109 clr<VAXfp:fsfx> %0
105 mov<VAXfp:fsfx> %1,%0") 110 mov<VAXfp:fsfx> %1,%0")
106 111
107;; Some VAXen don't support this instruction. 112;; Some VAXen don't support this instruction.
108;;(define_insn "movti" 113;;(define_insn "movti"
109;; [(set (match_operand:TI 0 "general_operand" "=g") 114;; [(set (match_operand:TI 0 "general_operand" "=g")
110;; (match_operand:TI 1 "general_operand" "g"))] 115;; (match_operand:TI 1 "general_operand" "g"))]
111;; "" 116;; ""
112;; "movh %1,%0") 117;; "movh %1,%0")
113 118
114(define_insn "movdi" 119(define_insn "movdi"
115 [(set (match_operand:DI 0 "nonimmediate_operand" "=g") 120 [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
116 (match_operand:DI 1 "general_operand" "g"))] 121 (match_operand:DI 1 "general_operand" "g"))]
117 "" 122 ""
118 "* return vax_output_int_move (insn, operands, DImode);") 123 "* return vax_output_int_move (insn, operands, DImode);")
119 124
120;; The VAX move instructions have space-time tradeoffs. On a MicroVAX 125;; The VAX move instructions have space-time tradeoffs. On a MicroVAX
121;; register-register mov instructions take 3 bytes and 2 CPU cycles. clrl 126;; register-register mov instructions take 3 bytes and 2 CPU cycles. clrl
122;; takes 2 bytes and 3 cycles. mov from constant to register takes 2 cycles 127;; takes 2 bytes and 3 cycles. mov from constant to register takes 2 cycles
123;; if the constant is smaller than 4 bytes, 3 cycles for a longword 128;; if the constant is smaller than 4 bytes, 3 cycles for a longword
124;; constant. movz, mneg, and mcom are as fast as mov, so movzwl is faster 129;; constant. movz, mneg, and mcom are as fast as mov, so movzwl is faster
125;; than movl for positive constants that fit in 16 bits but not 6 bits. cvt 130;; than movl for positive constants that fit in 16 bits but not 6 bits. cvt
126;; instructions take 4 cycles. inc takes 3 cycles. The machine description 131;; instructions take 4 cycles. inc takes 3 cycles. The machine description
127;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl 132;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl
128;; instead of movl). 133;; instead of movl).
129 134
130;; Cycle counts for other models may vary (on a VAX 750 they are similar, 135;; Cycle counts for other models may vary (on a VAX 750 they are similar,
131;; but on a VAX 9000 most move and add instructions with one constant 136;; but on a VAX 9000 most move and add instructions with one constant
132;; operand take 1 cycle). 137;; operand take 1 cycle).
133 138
134;; Loads of constants between 64 and 128 used to be done with 139;; Loads of constants between 64 and 128 used to be done with
135;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space. 140;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space.
136 141
137(define_expand "movsi" 142(define_expand "movsi"
138 [(set (match_operand:SI 0 "nonimmediate_operand" "") 143 [(set (match_operand:SI 0 "nonimmediate_operand" "")
139 (match_operand:SI 1 "general_operand" ""))] 144 (match_operand:SI 1 "general_operand" ""))]
140 "" 145 ""
141 " 146 "
142{ 147{
143#ifdef NO_EXTERNAL_INDIRECT_ADDRESS 148#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
144 if (flag_pic 149 if (flag_pic
145 && GET_CODE (operands[1]) == CONST 150 && GET_CODE (operands[1]) == CONST
146 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF 151 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF
147 && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (operands[1], 0), 0))) 152 && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (operands[1], 0), 0)))
148 { 153 {
149 rtx symbol_ref = XEXP (XEXP (operands[1], 0), 0); 154 rtx symbol_ref = XEXP (XEXP (operands[1], 0), 0);
150 rtx const_int = XEXP (XEXP (operands[1], 0), 1); 155 rtx const_int = XEXP (XEXP (operands[1], 0), 1);
151 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode); 156 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
152 emit_move_insn (temp, symbol_ref); 157 emit_move_insn (temp, symbol_ref);
153 emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, const_int)); 158 emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, const_int));
154 DONE; 159 DONE;
155 } 160 }
156#endif 161#endif
157}") 162}")
158 163
159(define_insn "movsi_2" 164(define_insn "movsi_2"
160 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 165 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
161 (match_operand:SI 1 "nonsymbolic_operand" "nrmT"))] 166 (match_operand:SI 1 "nonsymbolic_operand" "nrmT"))]
162 "" 167 ""
163 "* return vax_output_int_move (insn, operands, SImode);") 168 "* return vax_output_int_move (insn, operands, SImode);")
164 169
165(define_insn "mov<mode>" 170(define_insn "mov<mode>"
166 [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g") 171 [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g")
167 (match_operand:VAXintQH 1 "general_operand" "g"))] 172 (match_operand:VAXintQH 1 "general_operand" "g"))]
168 "" 173 ""
169 "* return vax_output_int_move (insn, operands, <MODE>mode);") 174 "* return vax_output_int_move (insn, operands, <MODE>mode);")
170 175
171(define_insn "movstricthi" 176(define_insn "movstricthi"
172 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g")) 177 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g"))
173 (match_operand:HI 1 "general_operand" "g"))] 178 (match_operand:HI 1 "general_operand" "g"))]
174 "" 179 ""
175 "* 180 "*
176{ 181{
177 if (CONST_INT_P (operands[1])) 182 if (CONST_INT_P (operands[1]))
178 { 183 {
179 int i = INTVAL (operands[1]); 184 int i = INTVAL (operands[1]);
180 if (i == 0) 185 if (i == 0)
181 return \"clrw %0\"; 186 return \"clrw %0\";
182 else if ((unsigned int)i < 64) 187 else if ((unsigned int)i < 64)
183 return \"movw %1,%0\"; 188 return \"movw %1,%0\";
184 else if ((unsigned int)~i < 64) 189 else if ((unsigned int)~i < 64)
185 return \"mcomw %H1,%0\"; 190 return \"mcomw %H1,%0\";
186 else if ((unsigned int)i < 256) 191 else if ((unsigned int)i < 256)
187 return \"movzbw %1,%0\"; 192 return \"movzbw %1,%0\";
188 } 193 }
189 return \"movw %1,%0\"; 194 return \"movw %1,%0\";
190}") 195}")
191 196
192(define_insn "movstrictqi" 197(define_insn "movstrictqi"
193 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g")) 198 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g"))
194 (match_operand:QI 1 "general_operand" "g"))] 199 (match_operand:QI 1 "general_operand" "g"))]
195 "" 200 ""
196 "* 201 "*
197{ 202{
198 if (CONST_INT_P (operands[1])) 203 if (CONST_INT_P (operands[1]))
199 { 204 {
200 int i = INTVAL (operands[1]); 205 int i = INTVAL (operands[1]);
201 if (i == 0) 206 if (i == 0)
202 return \"clrb %0\"; 207 return \"clrb %0\";
203 else if ((unsigned int)~i < 64) 208 else if ((unsigned int)~i < 64)
204 return \"mcomb %B1,%0\"; 209 return \"mcomb %B1,%0\";
205 } 210 }
206 return \"movb %1,%0\"; 211 return \"movb %1,%0\";
207}") 212}")
208 213
209;; This is here to accept 4 arguments and pass the first 3 along 214;; This is here to accept 4 arguments and pass the first 3 along
210;; to the movmemhi1 pattern that really does the work. 215;; to the movmemhi1 pattern that really does the work.
211(define_expand "movmemhi" 216(define_expand "movmemhi"
212 [(set (match_operand:BLK 0 "general_operand" "=g") 217 [(set (match_operand:BLK 0 "general_operand" "=g")
213 (match_operand:BLK 1 "general_operand" "g")) 218 (match_operand:BLK 1 "general_operand" "g"))
214 (use (match_operand:HI 2 "general_operand" "g")) 219 (use (match_operand:HI 2 "general_operand" "g"))
215 (match_operand 3 "" "")] 220 (match_operand 3 "" "")]
216 "" 221 ""
217 " 222 "
218{ 223{
219 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) <= 48) 224 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) <= 48)
220 { 225 {
221 emit_insn (gen_movmemsi1_2 (operands[0], operands[1], operands[2])); 226 emit_insn (gen_movmemsi1_2 (operands[0], operands[1], operands[2]));
222 DONE; 227 DONE;
223 } 228 }
224 emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2])); 229 emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2]));
225 DONE; 230 DONE;
226}") 231}")
227 232
228;; The definition of this insn does not really explain what it does, 233;; The definition of this insn does not really explain what it does,
229;; but it should suffice 234;; but it should suffice
230;; that anything generated as this insn will be recognized as one 235;; that anything generated as this insn will be recognized as one
231;; and that it won't successfully combine with anything. 236;; and that it won't successfully combine with anything.
232 237
233(define_insn "movmemsi1_2" 238(define_insn "movmemsi1_2"
234 [(set (match_operand:BLK 0 "memory_operand" "=B") 239 [(set (match_operand:BLK 0 "memory_operand" "=B")
235 (match_operand:BLK 1 "memory_operand" "B")) 240 (match_operand:BLK 1 "memory_operand" "B"))
236 (use (match_operand:SI 2 "const_int_operand" "g"))] 241 (use (match_operand:SI 2 "const_int_operand" "g"))]
237 "INTVAL (operands[2]) <= 48" 242 "INTVAL (operands[2]) <= 48"
238 "* return vax_output_movmemsi (insn, operands);") 243 "* return vax_output_movmemsi (insn, operands);")
239 244
240(define_insn "movmemhi1" 245(define_insn "movmemhi1"
241 [(set (match_operand:BLK 0 "memory_operand" "=o") 246 [(set (match_operand:BLK 0 "memory_operand" "=o")
242 (match_operand:BLK 1 "memory_operand" "o")) 247 (match_operand:BLK 1 "memory_operand" "o"))
243 (use (match_operand:HI 2 "general_operand" "g")) 248 (use (match_operand:HI 2 "general_operand" "g"))
244 (clobber (reg:SI 0)) 249 (clobber (reg:SI 0))
245 (clobber (reg:SI 1)) 250 (clobber (reg:SI 1))
246 (clobber (reg:SI 2)) 251 (clobber (reg:SI 2))
247 (clobber (reg:SI 3)) 252 (clobber (reg:SI 3))
248 (clobber (reg:SI 4)) 253 (clobber (reg:SI 4))
249 (clobber (reg:SI 5))] 254 (clobber (reg:SI 5))]
250 "" 255 ""
251 "movc3 %2,%1,%0") 256 "movc3 %2,%1,%0")
252  257
253;; Extension and truncation insns. 258;; Extension and truncation insns.
254 259
255(define_insn "truncsiqi2" 260(define_insn "truncsiqi2"
256 [(set (match_operand:QI 0 "nonimmediate_operand" "=g") 261 [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
257 (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))] 262 (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
258 "" 263 ""
259 "cvtlb %1,%0") 264 "cvtlb %1,%0")
260 265
261(define_insn "truncsihi2" 266(define_insn "truncsihi2"
262 [(set (match_operand:HI 0 "nonimmediate_operand" "=g") 267 [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
263 (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))] 268 (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
264 "" 269 ""
265 "cvtlw %1,%0") 270 "cvtlw %1,%0")
266 271
267(define_insn "trunchiqi2" 272(define_insn "trunchiqi2"
268 [(set (match_operand:QI 0 "nonimmediate_operand" "=g") 273 [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
269 (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))] 274 (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))]
270 "" 275 ""
271 "cvtwb %1,%0") 276 "cvtwb %1,%0")
272 277
273(define_insn "extendhisi2" 278(define_insn "extendhisi2"
274 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 279 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
275 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] 280 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
276 "" 281 ""
277 "cvtwl %1,%0") 282 "cvtwl %1,%0")
278 283
279(define_insn "extendqihi2" 284(define_insn "extendqihi2"
280 [(set (match_operand:HI 0 "nonimmediate_operand" "=g") 285 [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
281 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] 286 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
282 "" 287 ""
283 "cvtbw %1,%0") 288 "cvtbw %1,%0")
284 289
285(define_insn "extendqisi2" 290(define_insn "extendqisi2"
286 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 291 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
287 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] 292 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
288 "" 293 ""
289 "cvtbl %1,%0") 294 "cvtbl %1,%0")
290 295
291(define_insn "extendsfdf2" 296(define_insn "extendsfdf2"
292 [(set (match_operand:DF 0 "nonimmediate_operand" "=g") 297 [(set (match_operand:DF 0 "nonimmediate_operand" "=g")
293 (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))] 298 (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))]
294 "" 299 ""
295 "cvtf%# %1,%0") 300 "cvtf%# %1,%0")
296 301
297(define_insn "truncdfsf2" 302(define_insn "truncdfsf2"
298 [(set (match_operand:SF 0 "nonimmediate_operand" "=g") 303 [(set (match_operand:SF 0 "nonimmediate_operand" "=g")
299 (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))] 304 (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))]
300 "" 305 ""
301 "cvt%#f %1,%0") 306 "cvt%#f %1,%0")
302 307
303(define_insn "zero_extendhisi2" 308(define_insn "zero_extendhisi2"
304 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 309 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
305 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] 310 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
306 "" 311 ""
307 "movzwl %1,%0") 312 "movzwl %1,%0")
308 313
309(define_insn "zero_extendqihi2" 314(define_insn "zero_extendqihi2"
310 [(set (match_operand:HI 0 "nonimmediate_operand" "=g") 315 [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
311 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] 316 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
312 "" 317 ""
313 "movzbw %1,%0") 318 "movzbw %1,%0")
314 319
315(define_insn "zero_extendqisi2" 320(define_insn "zero_extendqisi2"
316 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 321 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
317 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] 322 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
318 "" 323 ""
319 "movzbl %1,%0") 324 "movzbl %1,%0")
320  325
321;; Fix-to-float conversion insns. 326;; Fix-to-float conversion insns.
322 327
323(define_insn "float<VAXint:mode><VAXfp:mode>2" 328(define_insn "float<VAXint:mode><VAXfp:mode>2"
324 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") 329 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
325 (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))] 330 (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))]
326 "" 331 ""
327 "cvt<VAXint:isfx><VAXfp:fsfx> %1,%0") 332 "cvt<VAXint:isfx><VAXfp:fsfx> %1,%0")
328 333
329;; Float-to-fix conversion insns. 334;; Float-to-fix conversion insns.
330 335
331(define_insn "fix_trunc<VAXfp:mode><VAXint:mode>2" 336(define_insn "fix_trunc<VAXfp:mode><VAXint:mode>2"
332 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") 337 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
333 (fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))] 338 (fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))]
334 "" 339 ""
335 "cvt<VAXfp:fsfx><VAXint:isfx> %1,%0") 340 "cvt<VAXfp:fsfx><VAXint:isfx> %1,%0")
336 341
337(define_expand "fixuns_trunc<VAXfp:mode><VAXint:mode>2" 342(define_expand "fixuns_trunc<VAXfp:mode><VAXint:mode>2"
338 [(set (match_operand:VAXint 0 "nonimmediate_operand" "") 343 [(set (match_operand:VAXint 0 "nonimmediate_operand" "")
339 (fix:VAXint (match_operand:VAXfp 1 "general_operand")))] 344 (fix:VAXint (match_operand:VAXfp 1 "general_operand")))]
340 "") 345 "")
341  346
342;;- All kinds of add instructions. 347;;- All kinds of add instructions.
343 348
344(define_insn "add<mode>3" 349(define_insn "add<mode>3"
345 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") 350 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
346 (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") 351 (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
347 (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))] 352 (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
348 "" 353 ""
349 "@ 354 "@
350 add<VAXfp:fsfx>2 %2,%0 355 add<VAXfp:fsfx>2 %2,%0
351 add<VAXfp:fsfx>2 %1,%0 356 add<VAXfp:fsfx>2 %1,%0
352 add<VAXfp:fsfx>3 %1,%2,%0") 357 add<VAXfp:fsfx>3 %1,%2,%0")
353 358
354(define_insn "pushlclsymreg" 359(define_insn "pushlclsymreg"
355 [(set (match_operand:SI 0 "push_operand" "=g") 360 [(set (match_operand:SI 0 "push_operand" "=g")
356 (plus:SI (match_operand:SI 1 "register_operand" "%r") 361 (plus:SI (match_operand:SI 1 "register_operand" "%r")
357 (match_operand:SI 2 "local_symbolic_operand" "i")))] 362 (match_operand:SI 2 "local_symbolic_operand" "i")))]
358 "flag_pic" 363 "flag_pic"
359 "pushab %a2[%1]") 364 "pushab %a2[%1]")
360 365
361(define_insn "pushextsymreg" 366(define_insn "pushextsymreg"
362 [(set (match_operand:SI 0 "push_operand" "=g") 367 [(set (match_operand:SI 0 "push_operand" "=g")
363 (plus:SI (match_operand:SI 1 "register_operand" "%r") 368 (plus:SI (match_operand:SI 1 "register_operand" "%r")
364 (match_operand:SI 2 "external_symbolic_operand" "i")))] 369 (match_operand:SI 2 "external_symbolic_operand" "i")))]
365 "flag_pic" 370 "flag_pic"
366 "pushab %a2[%1]") 371 "pushab %a2[%1]")
367 372
368(define_insn "movlclsymreg" 373(define_insn "movlclsymreg"
369 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 374 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
370 (plus:SI (match_operand:SI 1 "register_operand" "%r") 375 (plus:SI (match_operand:SI 1 "register_operand" "%r")
371 (match_operand:SI 2 "local_symbolic_operand" "i")))] 376 (match_operand:SI 2 "local_symbolic_operand" "i")))]
372 "flag_pic" 377 "flag_pic"
373 "movab %a2[%1],%0") 378 "movab %a2[%1],%0")
374 379
375(define_insn "movextsymreg" 380(define_insn "movextsymreg"
376 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 381 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
377 (plus:SI (match_operand:SI 1 "register_operand" "%r") 382 (plus:SI (match_operand:SI 1 "register_operand" "%r")
378 (match_operand:SI 2 "external_symbolic_operand" "i")))] 383 (match_operand:SI 2 "external_symbolic_operand" "i")))]
379 "flag_pic" 384 "flag_pic"
380 "movab %a2[%1],%0") 385 "movab %a2[%1],%0")
381 386
382(define_insn "add<mode>3" 387(define_insn "add<mode>3"
383 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") 388 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
384 (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT") 389 (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")
385 (match_operand:VAXint 2 "general_operand" "nrmT")))] 390 (match_operand:VAXint 2 "general_operand" "nrmT")))]
386 "" 391 ""
387 "* return vax_output_int_add (insn, operands, <MODE>mode);") 392 "* return vax_output_int_add (insn, operands, <MODE>mode);")
388 393
389(define_expand "adddi3" 394(define_expand "adddi3"
390 [(set (match_operand:DI 0 "nonimmediate_operand" "=g") 395 [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
391 (plus:DI (match_operand:DI 1 "general_operand" "g") 396 (plus:DI (match_operand:DI 1 "general_operand" "g")
392 (match_operand:DI 2 "general_operand" "g")))] 397 (match_operand:DI 2 "general_operand" "g")))]
393 "!reload_in_progress" 398 "!reload_in_progress"
394 "vax_expand_addsub_di_operands (operands, PLUS); DONE;") 399 "vax_expand_addsub_di_operands (operands, PLUS); DONE;")
395 400
396(define_insn "adcdi3" 401(define_insn "adcdi3"
397 [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr") 402 [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr")
398 (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0") 403 (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0")
399 (match_operand:DI 2 "general_addsub_di_operand" "nRr")))] 404 (match_operand:DI 2 "general_addsub_di_operand" "nRr")))]
400 "TARGET_QMATH" 405 "TARGET_QMATH"
401 "* return vax_output_int_add (insn, operands, DImode);") 406 "* return vax_output_int_add (insn, operands, DImode);")
402 407
403;; The add-with-carry (adwc) instruction only accepts two operands. 408;; The add-with-carry (adwc) instruction only accepts two operands.
404(define_insn "adddi3_old" 409(define_insn "adddi3_old"
405 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>") 410 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>")
406 (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>") 411 (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>")
407 (match_operand:DI 2 "general_operand" "Fsro,Fs")))] 412 (match_operand:DI 2 "general_operand" "Fsro,Fs")))]
408 "!TARGET_QMATH" 413 "!TARGET_QMATH"
409 "* return vax_output_int_add (insn, operands, DImode);") 414 "* return vax_output_int_add (insn, operands, DImode);")
410  415
411;;- All kinds of subtract instructions. 416;;- All kinds of subtract instructions.
412 417
413(define_insn "sub<mode>3" 418(define_insn "sub<mode>3"
414 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") 419 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
415 (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") 420 (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
416 (match_operand:VAXfp 2 "general_operand" "gF,gF")))] 421 (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
417 "" 422 ""
418 "@ 423 "@
419 sub<VAXfp:fsfx>2 %2,%0 424 sub<VAXfp:fsfx>2 %2,%0
420 sub<VAXfp:fsfx>3 %2,%1,%0") 425 sub<VAXfp:fsfx>3 %2,%1,%0")
421 426
422(define_insn "sub<mode>3" 427(define_insn "sub<mode>3"
423 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") 428 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
424 (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") 429 (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
425 (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))] 430 (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
426 "" 431 ""
427 "@ 432 "@
428 sub<VAXint:isfx>2 %2,%0 433 sub<VAXint:isfx>2 %2,%0
429 sub<VAXint:isfx>3 %2,%1,%0") 434 sub<VAXint:isfx>3 %2,%1,%0")
430 435
431(define_expand "subdi3" 436(define_expand "subdi3"
432 [(set (match_operand:DI 0 "nonimmediate_operand" "=g") 437 [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
433 (minus:DI (match_operand:DI 1 "general_operand" "g") 438 (minus:DI (match_operand:DI 1 "general_operand" "g")
434 (match_operand:DI 2 "general_operand" "g")))] 439 (match_operand:DI 2 "general_operand" "g")))]
435 "!reload_in_progress" 440 "!reload_in_progress"
436 "vax_expand_addsub_di_operands (operands, MINUS); DONE;") 441 "vax_expand_addsub_di_operands (operands, MINUS); DONE;")
437 442
438(define_insn "sbcdi3" 443(define_insn "sbcdi3"
439 [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr") 444 [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr")
440 (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I") 445 (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I")
441 (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))] 446 (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))]
442 "TARGET_QMATH" 447 "TARGET_QMATH"
443 "* return vax_output_int_subtract (insn, operands, DImode);") 448 "* return vax_output_int_subtract (insn, operands, DImode);")
444 449
445;; The subtract-with-carry (sbwc) instruction only takes two operands. 450;; The subtract-with-carry (sbwc) instruction only takes two operands.
446(define_insn "subdi3_old" 451(define_insn "subdi3_old"
447 [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>") 452 [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>")
448 (minus:DI (match_operand:DI 1 "general_operand" "0,or>") 453 (minus:DI (match_operand:DI 1 "general_operand" "0,or>")
449 (match_operand:DI 2 "general_operand" "Fsor,Fs")))] 454 (match_operand:DI 2 "general_operand" "Fsor,Fs")))]
450 "!TARGET_QMATH" 455 "!TARGET_QMATH"
451 "* return vax_output_int_subtract (insn, operands, DImode);") 456 "* return vax_output_int_subtract (insn, operands, DImode);")
452  457
453;;- Multiply instructions. 458;;- Multiply instructions.
454 459
455(define_insn "mul<mode>3" 460(define_insn "mul<mode>3"
456 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") 461 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
457 (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") 462 (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
458 (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))] 463 (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
459 "" 464 ""
460 "@ 465 "@
461 mul<VAXfp:fsfx>2 %2,%0 466 mul<VAXfp:fsfx>2 %2,%0
462 mul<VAXfp:fsfx>2 %1,%0 467 mul<VAXfp:fsfx>2 %1,%0
463 mul<VAXfp:fsfx>3 %1,%2,%0") 468 mul<VAXfp:fsfx>3 %1,%2,%0")
464 469
465(define_insn "mul<mode>3" 470(define_insn "mul<mode>3"
466 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") 471 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
467 (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") 472 (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
468 (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))] 473 (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
469 "" 474 ""
470 "@ 475 "@
471 mul<VAXint:isfx>2 %2,%0 476 mul<VAXint:isfx>2 %2,%0
472 mul<VAXint:isfx>2 %1,%0 477 mul<VAXint:isfx>2 %1,%0
473 mul<VAXint:isfx>3 %1,%2,%0") 478 mul<VAXint:isfx>3 %1,%2,%0")
474 479
475(define_insn "mulsidi3" 480(define_insn "mulsidi3"
476 [(set (match_operand:DI 0 "nonimmediate_operand" "=g") 481 [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
477 (mult:DI (sign_extend:DI 482 (mult:DI (sign_extend:DI
478 (match_operand:SI 1 "nonimmediate_operand" "nrmT")) 483 (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
479 (sign_extend:DI 484 (sign_extend:DI
480 (match_operand:SI 2 "nonimmediate_operand" "nrmT"))))] 485 (match_operand:SI 2 "nonimmediate_operand" "nrmT"))))]
481 "" 486 ""
482 "emul %1,%2,$0,%0") 487 "emul %1,%2,$0,%0")
483 488
484(define_insn "" 489(define_insn ""
485 [(set (match_operand:DI 0 "nonimmediate_operand" "=g") 490 [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
486 (plus:DI 491 (plus:DI
487 (mult:DI (sign_extend:DI 492 (mult:DI (sign_extend:DI
488 (match_operand:SI 1 "nonimmediate_operand" "nrmT")) 493 (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
489 (sign_extend:DI 494 (sign_extend:DI
490 (match_operand:SI 2 "nonimmediate_operand" "nrmT"))) 495 (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
491 (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))] 496 (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))]
492 "" 497 ""
493 "emul %1,%2,%3,%0") 498 "emul %1,%2,%3,%0")
494 499
495;; 'F' constraint means type CONST_DOUBLE 500;; 'F' constraint means type CONST_DOUBLE
496(define_insn "" 501(define_insn ""
497 [(set (match_operand:DI 0 "nonimmediate_operand" "=g") 502 [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
498 (plus:DI 503 (plus:DI
499 (mult:DI (sign_extend:DI 504 (mult:DI (sign_extend:DI
500 (match_operand:SI 1 "nonimmediate_operand" "nrmT")) 505 (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
501 (sign_extend:DI 506 (sign_extend:DI
502 (match_operand:SI 2 "nonimmediate_operand" "nrmT"))) 507 (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
503 (match_operand:DI 3 "immediate_operand" "F")))] 508 (match_operand:DI 3 "immediate_operand" "F")))]
504 "GET_CODE (operands[3]) == CONST_DOUBLE 509 "GET_CODE (operands[3]) == CONST_DOUBLE
505 && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)" 510 && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)"
506 "* 511 "*
507{ 512{
508 if (CONST_DOUBLE_HIGH (operands[3])) 513 if (CONST_DOUBLE_HIGH (operands[3]))
509 operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[3])); 514 operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[3]));
510 return \"emul %1,%2,%3,%0\"; 515 return \"emul %1,%2,%3,%0\";
511}") 516}")
512  517
513;;- Divide instructions. 518;;- Divide instructions.
514 519
515(define_insn "div<mode>3" 520(define_insn "div<mode>3"
516 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") 521 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
517 (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") 522 (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
518 (match_operand:VAXfp 2 "general_operand" "gF,gF")))] 523 (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
519 "" 524 ""
520 "@ 525 "@
521 div<VAXfp:fsfx>2 %2,%0 526 div<VAXfp:fsfx>2 %2,%0
522 div<VAXfp:fsfx>3 %2,%1,%0") 527 div<VAXfp:fsfx>3 %2,%1,%0")
523 528
524(define_insn "div<mode>3" 529(define_insn "div<mode>3"
525 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") 530 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
526 (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") 531 (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
527 (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))] 532 (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
528 "" 533 ""
529 "@ 534 "@
530 div<VAXint:isfx>2 %2,%0 535 div<VAXint:isfx>2 %2,%0
531 div<VAXint:isfx>3 %2,%1,%0") 536 div<VAXint:isfx>3 %2,%1,%0")
532 537
533;This is left out because it is very slow; 538;This is left out because it is very slow;
534;we are better off programming around the "lack" of this insn. 539;we are better off programming around the "lack" of this insn.
535;(define_insn "divmoddisi4" 540;(define_insn "divmoddisi4"
536; [(set (match_operand:SI 0 "general_operand" "=g") 541; [(set (match_operand:SI 0 "general_operand" "=g")
537; (div:SI (match_operand:DI 1 "general_operand" "g") 542; (div:SI (match_operand:DI 1 "general_operand" "g")
538; (match_operand:SI 2 "general_operand" "g"))) 543; (match_operand:SI 2 "general_operand" "g")))
539; (set (match_operand:SI 3 "general_operand" "=g") 544; (set (match_operand:SI 3 "general_operand" "=g")
540; (mod:SI (match_operand:DI 1 "general_operand" "g") 545; (mod:SI (match_operand:DI 1 "general_operand" "g")
541; (match_operand:SI 2 "general_operand" "g")))] 546; (match_operand:SI 2 "general_operand" "g")))]
542; "" 547; ""
543; "ediv %2,%1,%0,%3") 548; "ediv %2,%1,%0,%3")
544  549
545;; Bit-and on the VAX is done with a clear-bits insn. 550;; Bit-and on the VAX is done with a clear-bits insn.
546(define_expand "and<mode>3" 551(define_expand "and<mode>3"
547 [(set (match_operand:VAXint 0 "nonimmediate_operand" "") 552 [(set (match_operand:VAXint 0 "nonimmediate_operand" "")
548 (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "")) 553 (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" ""))
549 (match_operand:VAXint 2 "general_operand" "")))] 554 (match_operand:VAXint 2 "general_operand" "")))]
550 "" 555 ""
551 " 556 "
552{ 557{
553 rtx op1 = operands[1]; 558 rtx op1 = operands[1];
554 559
555 /* If there is a constant argument, complement that one. */ 560 /* If there is a constant argument, complement that one. */
556 if (CONST_INT_P (operands[2]) && ! CONST_INT_P (op1)) 561 if (CONST_INT_P (operands[2]) && ! CONST_INT_P (op1))
557 { 562 {
558 operands[1] = operands[2]; 563 operands[1] = operands[2];
559 operands[2] = op1; 564 operands[2] = op1;
560 op1 = operands[1]; 565 op1 = operands[1];
561 } 566 }
562 567
563 if (CONST_INT_P (op1)) 568 if (CONST_INT_P (op1))
564 operands[1] = GEN_INT (~INTVAL (op1)); 569 operands[1] = GEN_INT (~INTVAL (op1));
565 else 570 else
566 operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1); 571 operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1);
567}") 572}")
568 573
569(define_insn "*and<mode>" 574(define_insn "*and<mode>"
570 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") 575 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
571 (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT,nrmT")) 576 (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
572 (match_operand:VAXint 2 "general_operand" "0,nrmT")))] 577 (match_operand:VAXint 2 "general_operand" "0,nrmT")))]
573 "" 578 ""
574 "@ 579 "@
575 bic<VAXint:isfx>2 %1,%0 580 bic<VAXint:isfx>2 %1,%0
576 bic<VAXint:isfx>3 %1,%2,%0") 581 bic<VAXint:isfx>3 %1,%2,%0")
577 582
578;; The following used to be needed because constant propagation can 583;; The following used to be needed because constant propagation can
579;; create them starting from the bic insn patterns above. This is no 584;; create them starting from the bic insn patterns above. This is no
580;; longer a problem. However, having these patterns allows optimization 585;; longer a problem. However, having these patterns allows optimization
581;; opportunities in combine.c. 586;; opportunities in combine.c.
582 587
583(define_insn "*and<mode>_const_int" 588(define_insn "*and<mode>_const_int"
584 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") 589 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
585 (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") 590 (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
586 (match_operand:VAXint 2 "const_int_operand" "n,n")))] 591 (match_operand:VAXint 2 "const_int_operand" "n,n")))]
587 "" 592 ""
588 "@ 593 "@
589 bic<VAXint:isfx>2 %<VAXint:iprefx>2,%0 594 bic<VAXint:isfx>2 %<VAXint:iprefx>2,%0
590 bic<VAXint:isfx>3 %<VAXint:iprefx>2,%1,%0") 595 bic<VAXint:isfx>3 %<VAXint:iprefx>2,%1,%0")
591 596
592  597
593;;- Bit set instructions. 598;;- Bit set instructions.
594 599
595(define_insn "ior<mode>3" 600(define_insn "ior<mode>3"
596 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") 601 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
597 (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") 602 (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
598 (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))] 603 (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
599 "" 604 ""
600 "@ 605 "@
601 bis<VAXint:isfx>2 %2,%0 606 bis<VAXint:isfx>2 %2,%0
602 bis<VAXint:isfx>2 %1,%0 607 bis<VAXint:isfx>2 %1,%0
603 bis<VAXint:isfx>3 %2,%1,%0") 608 bis<VAXint:isfx>3 %2,%1,%0")
604 609
605;;- xor instructions. 610;;- xor instructions.
606 611
607(define_insn "xor<mode>3" 612(define_insn "xor<mode>3"
608 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") 613 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
609 (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") 614 (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
610 (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))] 615 (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
611 "" 616 ""
612 "@ 617 "@
613 xor<VAXint:isfx>2 %2,%0 618 xor<VAXint:isfx>2 %2,%0
614 xor<VAXint:isfx>2 %1,%0 619 xor<VAXint:isfx>2 %1,%0
615 xor<VAXint:isfx>3 %2,%1,%0") 620 xor<VAXint:isfx>3 %2,%1,%0")
616 621
617  622
618(define_insn "neg<mode>2" 623(define_insn "neg<mode>2"
619 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") 624 [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
620 (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))] 625 (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))]
621 "" 626 ""
622 "mneg<VAXfp:fsfx> %1,%0") 627 "mneg<VAXfp:fsfx> %1,%0")
623 628
624(define_insn "neg<mode>2" 629(define_insn "neg<mode>2"
625 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") 630 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
626 (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))] 631 (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
627 "" 632 ""
628 "mneg<VAXint:isfx> %1,%0") 633 "mneg<VAXint:isfx> %1,%0")
629 634
630(define_insn "one_cmpl<mode>2" 635(define_insn "one_cmpl<mode>2"
631 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") 636 [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
632 (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))] 637 (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
633 "" 638 ""
634 "mcom<VAXint:isfx> %1,%0") 639 "mcom<VAXint:isfx> %1,%0")
635 640
636  641
637;; Arithmetic right shift on the VAX works by negating the shift count, 642;; Arithmetic right shift on the VAX works by negating the shift count,
638;; then emitting a right shift with the shift count negated. This means 643;; then emitting a right shift with the shift count negated. This means
639;; that all actual shift counts in the RTL will be positive. This 644;; that all actual shift counts in the RTL will be positive. This
640;; prevents converting shifts to ZERO_EXTRACTs with negative positions, 645;; prevents converting shifts to ZERO_EXTRACTs with negative positions,
641;; which isn't valid. 646;; which isn't valid.
642(define_expand "ashrsi3" 647(define_expand "ashrsi3"
643 [(set (match_operand:SI 0 "general_operand" "=g") 648 [(set (match_operand:SI 0 "general_operand" "=g")
644 (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") 649 (ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
645 (match_operand:QI 2 "general_operand" "g")))] 650 (match_operand:QI 2 "general_operand" "g")))]
646 "" 651 ""
647 " 652 "
648{ 653{
649 if (! CONST_INT_P (operands[2])) 654 if (! CONST_INT_P (operands[2]))
650 operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); 655 operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
651}") 656}")
652 657
653(define_insn "" 658(define_insn ""
654 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 659 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
655 (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") 660 (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
656 (match_operand:QI 2 "const_int_operand" "n")))] 661 (match_operand:QI 2 "const_int_operand" "n")))]
657 "" 662 ""
658 "ashl $%n2,%1,%0") 663 "ashl $%n2,%1,%0")
659 664
660(define_insn "" 665(define_insn ""
661 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 666 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
662 (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") 667 (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
663 (neg:QI (match_operand:QI 2 "general_operand" "g"))))] 668 (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
664 "" 669 ""
665 "ashl %2,%1,%0") 670 "ashl %2,%1,%0")
666 671
667(define_insn "ashlsi3" 672(define_insn "ashlsi3"
668 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 673 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
669 (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") 674 (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
670 (match_operand:QI 2 "general_operand" "g")))] 675 (match_operand:QI 2 "general_operand" "g")))]
671 "" 676 ""
672 "* 677 "*
673{ 678{
674 if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1])) 679 if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1]))
675 return \"addl2 %0,%0\"; 680 return \"addl2 %0,%0\";
676 if (REG_P (operands[1]) && CONST_INT_P (operands[2])) 681 if (REG_P (operands[1]) && CONST_INT_P (operands[2]))
677 { 682 {
678 int i = INTVAL (operands[2]); 683 int i = INTVAL (operands[2]);
679 if (i == 1) 684 if (i == 1)
680 return \"addl3 %1,%1,%0\"; 685 return \"addl3 %1,%1,%0\";
681 if (i == 2 && !optimize_size) 686 if (i == 2 && !optimize_size)
682 { 687 {
683 if (push_operand (operands[0], SImode)) 688 if (push_operand (operands[0], SImode))
684 return \"pushal 0[%1]\"; 689 return \"pushal 0[%1]\";
685 return \"moval 0[%1],%0\"; 690 return \"moval 0[%1],%0\";
686 } 691 }
687 if (i == 3 && !optimize_size) 692 if (i == 3 && !optimize_size)
688 { 693 {
689 if (push_operand (operands[0], SImode)) 694 if (push_operand (operands[0], SImode))
690 return \"pushaq 0[%1]\"; 695 return \"pushaq 0[%1]\";
691 return \"movaq 0[%1],%0\"; 696 return \"movaq 0[%1],%0\";
692 } 697 }
693 } 698 }
694 return \"ashl %2,%1,%0\"; 699 return \"ashl %2,%1,%0\";
695}") 700}")
696 701
697;; Arithmetic right shift on the VAX works by negating the shift count. 702;; Arithmetic right shift on the VAX works by negating the shift count.
698(define_expand "ashrdi3" 703(define_expand "ashrdi3"
699 [(set (match_operand:DI 0 "general_operand" "=g") 704 [(set (match_operand:DI 0 "general_operand" "=g")
700 (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") 705 (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
701 (match_operand:QI 2 "general_operand" "g")))] 706 (match_operand:QI 2 "general_operand" "g")))]
702 "" 707 ""
703 " 708 "
704{ 709{
705 operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); 710 operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
706}") 711}")
707 712
708(define_insn "ashldi3" 713(define_insn "ashldi3"
709 [(set (match_operand:DI 0 "nonimmediate_operand" "=g") 714 [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
710 (ashift:DI (match_operand:DI 1 "general_operand" "g") 715 (ashift:DI (match_operand:DI 1 "general_operand" "g")
711 (match_operand:QI 2 "general_operand" "g")))] 716 (match_operand:QI 2 "general_operand" "g")))]
712 "" 717 ""
713 "ashq %2,%D1,%0") 718 "ashq %2,%D1,%0")
714 719
715(define_insn "" 720(define_insn ""
716 [(set (match_operand:DI 0 "nonimmediate_operand" "=g") 721 [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
717 (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") 722 (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
718 (neg:QI (match_operand:QI 2 "general_operand" "g"))))] 723 (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
719 "" 724 ""
720 "ashq %2,%D1,%0") 725 "ashq %2,%D1,%0")
721 726
722;; We used to have expand_shift handle logical right shifts by using extzv, 727;; We used to have expand_shift handle logical right shifts by using extzv,
723;; but this make it very difficult to do lshrdi3. Since the VAX is the 728;; but this make it very difficult to do lshrdi3. Since the VAX is the
724;; only machine with this kludge, it's better to just do this with a 729;; only machine with this kludge, it's better to just do this with a
725;; define_expand and remove that case from expand_shift. 730;; define_expand and remove that case from expand_shift.
726 731
727(define_expand "lshrsi3" 732(define_expand "lshrsi3"
728 [(set (match_dup 3) 733 [(set (match_dup 3)
729 (minus:QI (const_int 32) 734 (minus:QI (const_int 32)
730 (match_dup 4))) 735 (match_dup 4)))
731 (set (match_operand:SI 0 "nonimmediate_operand" "=g") 736 (set (match_operand:SI 0 "nonimmediate_operand" "=g")
732 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 737 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
733 (match_dup 3) 738 (match_dup 3)
734 (match_operand:SI 2 "register_operand" "g")))] 739 (match_operand:SI 2 "register_operand" "g")))]
735 "" 740 ""
736 " 741 "
737{ 742{
738 operands[3] = gen_reg_rtx (QImode); 743 operands[3] = gen_reg_rtx (QImode);
739 operands[4] = gen_lowpart (QImode, operands[2]); 744 operands[4] = gen_lowpart (QImode, operands[2]);
740}") 745}")
741 746
742;; Rotate right on the VAX works by negating the shift count. 747;; Rotate right on the VAX works by negating the shift count.
743(define_expand "rotrsi3" 748(define_expand "rotrsi3"
744 [(set (match_operand:SI 0 "general_operand" "=g") 749 [(set (match_operand:SI 0 "general_operand" "=g")
745 (rotatert:SI (match_operand:SI 1 "general_operand" "g") 750 (rotatert:SI (match_operand:SI 1 "general_operand" "g")
746 (match_operand:QI 2 "general_operand" "g")))] 751 (match_operand:QI 2 "general_operand" "g")))]
747 "" 752 ""
748 " 753 "
749{ 754{
750 if (! CONST_INT_P (operands[2])) 755 if (! CONST_INT_P (operands[2]))
751 operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); 756 operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
752}") 757}")
753 758
754(define_insn "rotlsi3" 759(define_insn "rotlsi3"
755 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 760 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
756 (rotate:SI (match_operand:SI 1 "general_operand" "nrmT") 761 (rotate:SI (match_operand:SI 1 "general_operand" "nrmT")
757 (match_operand:QI 2 "general_operand" "g")))] 762 (match_operand:QI 2 "general_operand" "g")))]
758 "" 763 ""
759 "rotl %2,%1,%0") 764 "rotl %2,%1,%0")
760 765
761(define_insn "" 766(define_insn ""
762 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 767 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
763 (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") 768 (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
764 (match_operand:QI 2 "const_int_operand" "n")))] 769 (match_operand:QI 2 "const_int_operand" "n")))]
765 "" 770 ""
766 "rotl %R2,%1,%0") 771 "rotl %R2,%1,%0")
767 772
768(define_insn "" 773(define_insn ""
769 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 774 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
770 (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") 775 (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
771 (neg:QI (match_operand:QI 2 "general_operand" "g"))))] 776 (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
772 "" 777 ""
773 "rotl %2,%1,%0") 778 "rotl %2,%1,%0")
774 779
775;This insn is probably slower than a multiply and an add. 780;This insn is probably slower than a multiply and an add.
776;(define_insn "" 781;(define_insn ""
777; [(set (match_operand:SI 0 "general_operand" "=g") 782; [(set (match_operand:SI 0 "general_operand" "=g")
778; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") 783; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
779; (match_operand:SI 2 "general_operand" "g")) 784; (match_operand:SI 2 "general_operand" "g"))
780; (match_operand:SI 3 "general_operand" "g")))] 785; (match_operand:SI 3 "general_operand" "g")))]
781; "" 786; ""
782; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0") 787; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0")
783  788
784;; Special cases of bit-field insns which we should 789;; Special cases of bit-field insns which we should
785;; recognize in preference to the general case. 790;; recognize in preference to the general case.
786;; These handle aligned 8-bit and 16-bit fields, 791;; These handle aligned 8-bit and 16-bit fields,
787;; which can usually be done with move instructions. 792;; which can usually be done with move instructions.
788 793
789;; netbsd changed this to REG_P (operands[0]) || (MEM_P (operands[0]) && ... 794;; netbsd changed this to REG_P (operands[0]) || (MEM_P (operands[0]) && ...
790;; but gcc made it just !MEM_P (operands[0]) || ... 795;; but gcc made it just !MEM_P (operands[0]) || ...
791 796
792(define_insn "" 797(define_insn ""
793 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro") 798 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro")
794 (match_operand:QI 1 "const_int_operand" "n") 799 (match_operand:QI 1 "const_int_operand" "n")
795 (match_operand:SI 2 "const_int_operand" "n")) 800 (match_operand:SI 2 "const_int_operand" "n"))
796 (match_operand:SI 3 "general_operand" "g"))] 801 (match_operand:SI 3 "general_operand" "g"))]
797 "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) 802 "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
798 && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 803 && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
799 && (REG_P (operands[0]) 804 && (REG_P (operands[0])
800 || (MEM_P (operands[0]) 805 || (MEM_P (operands[0])
801 && ! mode_dependent_address_p (XEXP (operands[0], 0), 806 && ! mode_dependent_address_p (XEXP (operands[0], 0),
802 MEM_ADDR_SPACE (operands[0]))))" 807 MEM_ADDR_SPACE (operands[0]))))"
803 "* 808 "*
804{ 809{
805 if (REG_P (operands[0])) 810 if (REG_P (operands[0]))
806 { 811 {
807 if (INTVAL (operands[2]) != 0) 812 if (INTVAL (operands[2]) != 0)
808 return \"insv %3,%2,%1,%0\"; 813 return \"insv %3,%2,%1,%0\";
809 } 814 }
810 else 815 else
811 operands[0] 816 operands[0]
812 = adjust_address (operands[0], 817 = adjust_address (operands[0],
813 INTVAL (operands[1]) == 8 ? QImode : HImode, 818 INTVAL (operands[1]) == 8 ? QImode : HImode,
814 INTVAL (operands[2]) / 8); 819 INTVAL (operands[2]) / 8);
815 820
816 CC_STATUS_INIT; 821 CC_STATUS_INIT;
817 if (INTVAL (operands[1]) == 8) 822 if (INTVAL (operands[1]) == 8)
818 return \"movb %3,%0\"; 823 return \"movb %3,%0\";
819 return \"movw %3,%0\"; 824 return \"movw %3,%0\";
820}") 825}")
821 826
822(define_insn "" 827(define_insn ""
823 [(set (match_operand:SI 0 "nonimmediate_operand" "=&g") 828 [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
824 (zero_extract:SI (match_operand:SI 1 "register_operand" "ro") 829 (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
825 (match_operand:QI 2 "const_int_operand" "n") 830 (match_operand:QI 2 "const_int_operand" "n")
826 (match_operand:SI 3 "const_int_operand" "n")))] 831 (match_operand:SI 3 "const_int_operand" "n")))]
827 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) 832 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
828 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 833 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
829 && (REG_P (operands[1]) 834 && (REG_P (operands[1])
830 || (MEM_P (operands[1]) 835 || (MEM_P (operands[1])
831 && ! mode_dependent_address_p (XEXP (operands[1], 0), 836 && ! mode_dependent_address_p (XEXP (operands[1], 0),
832 MEM_ADDR_SPACE (operands[1]))))" 837 MEM_ADDR_SPACE (operands[1]))))"
833 "* 838 "*
834{ 839{
835 if (REG_P (operands[1])) 840 if (REG_P (operands[1]))
836 { 841 {
837 if (INTVAL (operands[3]) != 0) 842 if (INTVAL (operands[3]) != 0)
838 return \"extzv %3,%2,%1,%0\"; 843 return \"extzv %3,%2,%1,%0\";
839 } 844 }
840 else 845 else
841 operands[1] 846 operands[1]
842 = adjust_address (operands[1], 847 = adjust_address (operands[1],
843 INTVAL (operands[2]) == 8 ? QImode : HImode, 848 INTVAL (operands[2]) == 8 ? QImode : HImode,
844 INTVAL (operands[3]) / 8); 849 INTVAL (operands[3]) / 8);
845 850
846 if (INTVAL (operands[2]) == 8) 851 if (INTVAL (operands[2]) == 8)
847 return \"movzbl %1,%0\"; 852 return \"movzbl %1,%0\";
848 return \"movzwl %1,%0\"; 853 return \"movzwl %1,%0\";
849}") 854}")
850 855
851(define_insn "" 856(define_insn ""
852 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 857 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
853 (sign_extract:SI (match_operand:SI 1 "register_operand" "ro") 858 (sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
854 (match_operand:QI 2 "const_int_operand" "n") 859 (match_operand:QI 2 "const_int_operand" "n")
855 (match_operand:SI 3 "const_int_operand" "n")))] 860 (match_operand:SI 3 "const_int_operand" "n")))]
856 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) 861 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
857 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 862 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
858 && (REG_P (operands[1]) 863 && (REG_P (operands[1])
859 || (MEM_P (operands[1]) 864 || (MEM_P (operands[1])
860 && ! mode_dependent_address_p (XEXP (operands[1], 0), 865 && ! mode_dependent_address_p (XEXP (operands[1], 0),
861 MEM_ADDR_SPACE (operands[1]))))" 866 MEM_ADDR_SPACE (operands[1]))))"
862 "* 867 "*
863{ 868{
864 if (REG_P (operands[1])) 869 if (REG_P (operands[1]))
865 { 870 {
866 if (INTVAL (operands[3]) != 0) 871 if (INTVAL (operands[3]) != 0)
867 return \"extv %3,%2,%1,%0\"; 872 return \"extv %3,%2,%1,%0\";
868 } 873 }
869 else 874 else
870 operands[1] 875 operands[1]
871 = adjust_address (operands[1], 876 = adjust_address (operands[1],
872 INTVAL (operands[2]) == 8 ? QImode : HImode, 877 INTVAL (operands[2]) == 8 ? QImode : HImode,
873 INTVAL (operands[3]) / 8); 878 INTVAL (operands[3]) / 8);
874 879
875 if (INTVAL (operands[2]) == 8) 880 if (INTVAL (operands[2]) == 8)
876 return \"cvtbl %1,%0\"; 881 return \"cvtbl %1,%0\";
877 return \"cvtwl %1,%0\"; 882 return \"cvtwl %1,%0\";
878}") 883}")
879  884
880;; Register-only SImode cases of bit-field insns. 885;; Register-only SImode cases of bit-field insns.
881 886
882(define_insn "" 887(define_insn ""
883 [(set (cc0) 888 [(set (cc0)
884 (compare 889 (compare
885 (sign_extract:SI (match_operand:SI 0 "register_operand" "r") 890 (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
886 (match_operand:QI 1 "general_operand" "g") 891 (match_operand:QI 1 "general_operand" "g")
887 (match_operand:SI 2 "general_operand" "nrmT")) 892 (match_operand:SI 2 "general_operand" "nrmT"))
888 (match_operand:SI 3 "general_operand" "nrmT")))] 893 (match_operand:SI 3 "general_operand" "nrmT")))]
889 "" 894 ""
890 "cmpv %2,%1,%0,%3") 895 "cmpv %2,%1,%0,%3")
891 896
892(define_insn "" 897(define_insn ""
893 [(set (cc0) 898 [(set (cc0)
894 (compare 899 (compare
895 (zero_extract:SI (match_operand:SI 0 "register_operand" "r") 900 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
896 (match_operand:QI 1 "general_operand" "g") 901 (match_operand:QI 1 "general_operand" "g")
897 (match_operand:SI 2 "general_operand" "nrmT")) 902 (match_operand:SI 2 "general_operand" "nrmT"))
898 (match_operand:SI 3 "general_operand" "nrmT")))] 903 (match_operand:SI 3 "general_operand" "nrmT")))]
899 "" 904 ""
900 "cmpzv %2,%1,%0,%3") 905 "cmpzv %2,%1,%0,%3")
901 906
902;; When the field position and size are constant and the destination 907;; When the field position and size are constant and the destination
903;; is a register, extv and extzv are much slower than a rotate followed 908;; is a register, extv and extzv are much slower than a rotate followed
904;; by a bicl or sign extension. Because we might end up choosing ext[z]v 909;; by a bicl or sign extension. Because we might end up choosing ext[z]v
905;; anyway, we can't allow immediate values for the primary source operand. 910;; anyway, we can't allow immediate values for the primary source operand.
906 911
907(define_insn "" 912(define_insn ""
908 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 913 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
909 (sign_extract:SI (match_operand:SI 1 "register_operand" "ro") 914 (sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
910 (match_operand:QI 2 "general_operand" "g") 915 (match_operand:QI 2 "general_operand" "g")
911 (match_operand:SI 3 "general_operand" "nrmT")))] 916 (match_operand:SI 3 "general_operand" "nrmT")))]
912 "" 917 ""
913 "* 918 "*
914{ 919{
915 if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2]) 920 if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
916 || ! REG_P (operands[0]) 921 || ! REG_P (operands[0])
917 || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)) 922 || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16))
918 return \"extv %3,%2,%1,%0\"; 923 return \"extv %3,%2,%1,%0\";
919 if (INTVAL (operands[2]) == 8) 924 if (INTVAL (operands[2]) == 8)
920 return \"rotl %R3,%1,%0\;cvtbl %0,%0\"; 925 return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
921 return \"rotl %R3,%1,%0\;cvtwl %0,%0\"; 926 return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
922}") 927}")
923 928
924(define_insn "" 929(define_insn ""
925 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 930 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
926 (zero_extract:SI (match_operand:SI 1 "register_operand" "ro") 931 (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
927 (match_operand:QI 2 "general_operand" "g") 932 (match_operand:QI 2 "general_operand" "g")
928 (match_operand:SI 3 "general_operand" "nrmT")))] 933 (match_operand:SI 3 "general_operand" "nrmT")))]
929 "" 934 ""
930 "* 935 "*
931{ 936{
932 if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2]) 937 if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
933 || ! REG_P (operands[0])) 938 || ! REG_P (operands[0]))
934 return \"extzv %3,%2,%1,%0\"; 939 return \"extzv %3,%2,%1,%0\";
935 if (INTVAL (operands[2]) == 8) 940 if (INTVAL (operands[2]) == 8)
936 return \"rotl %R3,%1,%0\;movzbl %0,%0\"; 941 return \"rotl %R3,%1,%0\;movzbl %0,%0\";
937 if (INTVAL (operands[2]) == 16) 942 if (INTVAL (operands[2]) == 16)
938 return \"rotl %R3,%1,%0\;movzwl %0,%0\"; 943 return \"rotl %R3,%1,%0\;movzwl %0,%0\";
939 if (INTVAL (operands[3]) & 31) 944 if (INTVAL (operands[3]) & 31)
940 return \"rotl %R3,%1,%0\;bicl2 %M2,%0\"; 945 return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
941 if (rtx_equal_p (operands[0], operands[1])) 946 if (rtx_equal_p (operands[0], operands[1]))
942 return \"bicl2 %M2,%0\"; 947 return \"bicl2 %M2,%0\";
943 return \"bicl3 %M2,%1,%0\"; 948 return \"bicl3 %M2,%1,%0\";
944}") 949}")
945 950
946;; Non-register cases. 951;; Non-register cases.
947;; nonimmediate_operand is used to make sure that mode-ambiguous cases 952;; nonimmediate_operand is used to make sure that mode-ambiguous cases
948;; don't match these (and therefore match the cases above instead). 953;; don't match these (and therefore match the cases above instead).
949 954
950(define_insn "" 955(define_insn ""
951 [(set (cc0) 956 [(set (cc0)
952 (compare 957 (compare
953 (sign_extract:SI (match_operand:QI 0 "memory_operand" "m") 958 (sign_extract:SI (match_operand:QI 0 "memory_operand" "m")
954 (match_operand:QI 1 "general_operand" "g") 959 (match_operand:QI 1 "general_operand" "g")
955 (match_operand:SI 2 "general_operand" "nrmT")) 960 (match_operand:SI 2 "general_operand" "nrmT"))
956 (match_operand:SI 3 "general_operand" "nrmT")))] 961 (match_operand:SI 3 "general_operand" "nrmT")))]
957 "" 962 ""
958 "cmpv %2,%1,%0,%3") 963 "cmpv %2,%1,%0,%3")
959 964
960(define_insn "" 965(define_insn ""
961 [(set (cc0) 966 [(set (cc0)
962 (compare 967 (compare
963 (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm") 968 (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
964 (match_operand:QI 1 "general_operand" "g") 969 (match_operand:QI 1 "general_operand" "g")
965 (match_operand:SI 2 "general_operand" "nrmT")) 970 (match_operand:SI 2 "general_operand" "nrmT"))
966 (match_operand:SI 3 "general_operand" "nrmT")))] 971 (match_operand:SI 3 "general_operand" "nrmT")))]
967 "" 972 ""
968 "cmpzv %2,%1,%0,%3") 973 "cmpzv %2,%1,%0,%3")
969 974
970(define_insn "extv" 975(define_insn "extv"
971 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 976 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
972 (sign_extract:SI (match_operand:QI 1 "memory_operand" "m") 977 (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
973 (match_operand:QI 2 "general_operand" "g") 978 (match_operand:QI 2 "general_operand" "g")
974 (match_operand:SI 3 "general_operand" "nrmT")))] 979 (match_operand:SI 3 "general_operand" "nrmT")))]
975 "" 980 ""
976 "* 981 "*
977{ 982{
978 if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2]) 983 if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
979 || ! CONST_INT_P (operands[3]) 984 || ! CONST_INT_P (operands[3])
980 || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16) 985 || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
981 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32 986 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
982 || side_effects_p (operands[1]) 987 || side_effects_p (operands[1])
983 || (MEM_P (operands[1]) 988 || (MEM_P (operands[1])
984 && mode_dependent_address_p (XEXP (operands[1], 0), 989 && mode_dependent_address_p (XEXP (operands[1], 0),
985 MEM_ADDR_SPACE (operands[1])))) 990 MEM_ADDR_SPACE (operands[1]))))
986 return \"extv %3,%2,%1,%0\"; 991 return \"extv %3,%2,%1,%0\";
987 if (INTVAL (operands[2]) == 8) 992 if (INTVAL (operands[2]) == 8)
988 return \"rotl %R3,%1,%0\;cvtbl %0,%0\"; 993 return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
989 return \"rotl %R3,%1,%0\;cvtwl %0,%0\"; 994 return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
990}") 995}")
991 996
992(define_expand "extzv" 997(define_expand "extzv"
993 [(set (match_operand:SI 0 "general_operand" "") 998 [(set (match_operand:SI 0 "general_operand" "")
994 (zero_extract:SI (match_operand:SI 1 "general_operand" "") 999 (zero_extract:SI (match_operand:SI 1 "general_operand" "")
995 (match_operand:QI 2 "general_operand" "") 1000 (match_operand:QI 2 "general_operand" "")
996 (match_operand:SI 3 "general_operand" "")))] 1001 (match_operand:SI 3 "general_operand" "")))]
997 "" 1002 ""
998 "") 1003 "")
999 1004
1000(define_insn "" 1005(define_insn ""
1001 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 1006 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1002 (zero_extract:SI (match_operand:QI 1 "memory_operand" "m") 1007 (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
1003 (match_operand:QI 2 "general_operand" "g") 1008 (match_operand:QI 2 "general_operand" "g")
1004 (match_operand:SI 3 "general_operand" "nrmT")))] 1009 (match_operand:SI 3 "general_operand" "nrmT")))]
1005 "" 1010 ""
1006 "* 1011 "*
1007{ 1012{
1008 if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2]) 1013 if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
1009 || ! CONST_INT_P (operands[3]) 1014 || ! CONST_INT_P (operands[3])
1010 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32 1015 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
1011 || side_effects_p (operands[1]) 1016 || side_effects_p (operands[1])
1012 || (MEM_P (operands[1]) 1017 || (MEM_P (operands[1])
1013 && mode_dependent_address_p (XEXP (operands[1], 0), 1018 && mode_dependent_address_p (XEXP (operands[1], 0),
1014 MEM_ADDR_SPACE (operands[1])))) 1019 MEM_ADDR_SPACE (operands[1]))))
1015 return \"extzv %3,%2,%1,%0\"; 1020 return \"extzv %3,%2,%1,%0\";
1016 if (INTVAL (operands[2]) == 8) 1021 if (INTVAL (operands[2]) == 8)
1017 return \"rotl %R3,%1,%0\;movzbl %0,%0\"; 1022 return \"rotl %R3,%1,%0\;movzbl %0,%0\";
1018 if (INTVAL (operands[2]) == 16) 1023 if (INTVAL (operands[2]) == 16)
1019 return \"rotl %R3,%1,%0\;movzwl %0,%0\"; 1024 return \"rotl %R3,%1,%0\;movzwl %0,%0\";
1020 if (MEM_P (operands[1]) 1025 if (MEM_P (operands[1])
1021 && GET_CODE (XEXP (operands[1], 0)) == PLUS 1026 && GET_CODE (XEXP (operands[1], 0)) == PLUS
1022 && REG_P (XEXP (XEXP (operands[1], 0), 0)) 1027 && REG_P (XEXP (XEXP (operands[1], 0), 0))
1023 && CONST_INT_P (XEXP (XEXP (operands[1], 0), 1)) 1028 && CONST_INT_P (XEXP (XEXP (operands[1], 0), 1))
1024 && CONST_INT_P (operands[2]) 1029 && CONST_INT_P (operands[2])
1025 && CONST_INT_P (operands[3])) 1030 && CONST_INT_P (operands[3]))
1026 { 1031 {
1027 HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[1], 0), 1)); 1032 HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[1], 0), 1));
1028 HOST_WIDE_INT l = INTVAL (operands[2]); 1033 HOST_WIDE_INT l = INTVAL (operands[2]);
1029 HOST_WIDE_INT v = INTVAL (operands[3]); 1034 HOST_WIDE_INT v = INTVAL (operands[3]);
1030 if ((o & 3) && (o & 3) * 8 + v + l <= 32) 1035 if ((o & 3) && (o & 3) * 8 + v + l <= 32)
1031 { 1036 {
1032 rtx tmp; 1037 rtx tmp;
1033 tmp = XEXP (XEXP (operands[1], 0), 0); 1038 tmp = XEXP (XEXP (operands[1], 0), 0);
1034 if (o & ~3) 1039 if (o & ~3)
1035 tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3)); 1040 tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1036 operands[1] = gen_rtx_MEM (QImode, tmp); 1041 operands[1] = gen_rtx_MEM (QImode, tmp);
1037 operands[3] = GEN_INT (v + (o & 3) * 8); 1042 operands[3] = GEN_INT (v + (o & 3) * 8);
1038 } 1043 }
1039 if (optimize_size) 1044 if (optimize_size)
1040 return \"extzv %3,%2,%1,%0\"; 1045 return \"extzv %3,%2,%1,%0\";
1041 } 1046 }
1042 return \"rotl %R3,%1,%0\;bicl2 %M2,%0\"; 1047 return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
1043}") 1048}")
1044 1049
1045(define_expand "insv" 1050(define_expand "insv"
1046 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "") 1051 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
1047 (match_operand:QI 1 "general_operand" "") 1052 (match_operand:QI 1 "general_operand" "")
1048 (match_operand:SI 2 "general_operand" "")) 1053 (match_operand:SI 2 "general_operand" ""))
1049 (match_operand:SI 3 "general_operand" ""))] 1054 (match_operand:SI 3 "general_operand" ""))]
1050 "" 1055 ""
1051 "") 1056 "")
1052 1057
1053(define_insn "" 1058(define_insn ""
1054 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g") 1059 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g")
1055 (match_operand:QI 1 "general_operand" "g") 1060 (match_operand:QI 1 "general_operand" "g")
1056 (match_operand:SI 2 "general_operand" "nrmT")) 1061 (match_operand:SI 2 "general_operand" "nrmT"))
1057 (match_operand:SI 3 "general_operand" "nrmT"))] 1062 (match_operand:SI 3 "general_operand" "nrmT"))]
1058 "" 1063 ""
1059 "* 1064 "*
1060{ 1065{
1061 if (MEM_P (operands[0]) 1066 if (MEM_P (operands[0])
1062 && GET_CODE (XEXP (operands[0], 0)) == PLUS 1067 && GET_CODE (XEXP (operands[0], 0)) == PLUS
1063 && REG_P (XEXP (XEXP (operands[0], 0), 0)) 1068 && REG_P (XEXP (XEXP (operands[0], 0), 0))
1064 && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1)) 1069 && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1))
1065 && CONST_INT_P (operands[1]) 1070 && CONST_INT_P (operands[1])
1066 && CONST_INT_P (operands[2])) 1071 && CONST_INT_P (operands[2]))
1067 { 1072 {
1068 HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[0], 0), 1)); 1073 HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1069 HOST_WIDE_INT v = INTVAL (operands[2]); 1074 HOST_WIDE_INT v = INTVAL (operands[2]);
1070 HOST_WIDE_INT l = INTVAL (operands[1]); 1075 HOST_WIDE_INT l = INTVAL (operands[1]);
1071 if ((o & 3) && (o & 3) * 8 + v + l <= 32) 1076 if ((o & 3) && (o & 3) * 8 + v + l <= 32)
1072 { 1077 {
1073 rtx tmp; 1078 rtx tmp;
1074 tmp = XEXP (XEXP (operands[0], 0), 0); 1079 tmp = XEXP (XEXP (operands[0], 0), 0);
1075 if (o & ~3) 1080 if (o & ~3)
1076 tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3)); 1081 tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1077 operands[0] = gen_rtx_MEM (QImode, tmp); 1082 operands[0] = gen_rtx_MEM (QImode, tmp);
1078 operands[2] = GEN_INT (v + (o & 3) * 8); 1083 operands[2] = GEN_INT (v + (o & 3) * 8);
1079 } 1084 }
1080 } 1085 }
1081 return \"insv %3,%2,%1,%0\"; 1086 return \"insv %3,%2,%1,%0\";
1082}") 1087}")
1083 1088
1084(define_insn "" 1089(define_insn ""
1085 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 1090 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1086 (match_operand:QI 1 "general_operand" "g") 1091 (match_operand:QI 1 "general_operand" "g")
1087 (match_operand:SI 2 "general_operand" "nrmT")) 1092 (match_operand:SI 2 "general_operand" "nrmT"))
1088 (match_operand:SI 3 "general_operand" "nrmT"))] 1093 (match_operand:SI 3 "general_operand" "nrmT"))]
1089 "" 1094 ""
1090 "insv %3,%2,%1,%0") 1095 "insv %3,%2,%1,%0")
1091  1096
1092;; Unconditional jump 1097;; Unconditional jump
1093(define_insn "jump" 1098(define_insn "jump"
1094 [(set (pc) 1099 [(set (pc)
1095 (label_ref (match_operand 0 "" "")))] 1100 (label_ref (match_operand 0 "" "")))]
1096 "" 1101 ""
1097 "jbr %l0") 1102 "jbr %l0")
1098 1103
1099;; Conditional jumps 1104;; Conditional jumps
1100 1105
1101(define_expand "cbranch<mode>4" 1106(define_expand "cbranch<mode>4"
1102 [(set (cc0) 1107 [(set (cc0)
1103 (compare (match_operand:VAXint 1 "nonimmediate_operand" "") 1108 (compare (match_operand:VAXint 1 "nonimmediate_operand" "")
1104 (match_operand:VAXint 2 "general_operand" ""))) 1109 (match_operand:VAXint 2 "general_operand" "")))
1105 (set (pc) 1110 (set (pc)
1106 (if_then_else 1111 (if_then_else
1107 (match_operator 0 "ordered_comparison_operator" [(cc0) 1112 (match_operator 0 "ordered_comparison_operator" [(cc0)
1108 (const_int 0)]) 1113 (const_int 0)])
1109 (label_ref (match_operand 3 "" "")) 1114 (label_ref (match_operand 3 "" ""))
1110 (pc)))] 1115 (pc)))]
1111 "") 1116 "")
1112 1117
1113(define_expand "cbranch<mode>4" 1118(define_expand "cbranch<mode>4"
1114 [(set (cc0) 1119 [(set (cc0)
1115 (compare (match_operand:VAXfp 1 "general_operand" "") 1120 (compare (match_operand:VAXfp 1 "general_operand" "")
1116 (match_operand:VAXfp 2 "general_operand" ""))) 1121 (match_operand:VAXfp 2 "general_operand" "")))
1117 (set (pc) 1122 (set (pc)
1118 (if_then_else 1123 (if_then_else
1119 (match_operator 0 "ordered_comparison_operator" [(cc0) 1124 (match_operator 0 "ordered_comparison_operator" [(cc0)
1120 (const_int 0)]) 1125 (const_int 0)])
1121 (label_ref (match_operand 3 "" "")) 1126 (label_ref (match_operand 3 "" ""))
1122 (pc)))] 1127 (pc)))]
1123 "") 1128 "")
1124 1129
1125(define_insn "*branch" 1130(define_insn "*branch"
1126 [(set (pc) 1131 [(set (pc)
1127 (if_then_else (match_operator 0 "ordered_comparison_operator" 1132 (if_then_else (match_operator 0 "ordered_comparison_operator"
1128 [(cc0) 1133 [(cc0)
1129 (const_int 0)]) 1134 (const_int 0)])
1130 (label_ref (match_operand 1 "" "")) 1135 (label_ref (match_operand 1 "" ""))
1131 (pc)))] 1136 (pc)))]
1132 "" 1137 ""
1133 "j%c0 %l1") 1138 "j%c0 %l1")
1134 1139
1135;; Recognize reversed jumps. 1140;; Recognize reversed jumps.
1136(define_insn "*branch_reversed" 1141(define_insn "*branch_reversed"
1137 [(set (pc) 1142 [(set (pc)
1138 (if_then_else (match_operator 0 "ordered_comparison_operator" 1143 (if_then_else (match_operator 0 "ordered_comparison_operator"
1139 [(cc0) 1144 [(cc0)
1140 (const_int 0)]) 1145 (const_int 0)])
1141 (pc) 1146 (pc)
1142 (label_ref (match_operand 1 "" ""))))] 1147 (label_ref (match_operand 1 "" ""))))]
1143 "" 1148 ""
1144 "j%C0 %l1") ; %C0 negates condition 1149 "j%C0 %l1") ; %C0 negates condition
1145  1150
1146;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand 1151;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand
1147;; of jlbs and jlbc insns are SImode in the hardware. However, if it is 1152;; of jlbs and jlbc insns are SImode in the hardware. However, if it is
1148;; memory, we use QImode in the insn. So we can't use those instructions 1153;; memory, we use QImode in the insn. So we can't use those instructions
1149;; for mode-dependent addresses. 1154;; for mode-dependent addresses.
1150 1155
1151(define_insn "" 1156(define_insn ""
1152 [(set (pc) 1157 [(set (pc)
1153 (if_then_else 1158 (if_then_else
1154 (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g") 1159 (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1155 (const_int 1) 1160 (const_int 1)
1156 (match_operand:SI 1 "general_operand" "I,nrmT")) 1161 (match_operand:SI 1 "general_operand" "I,nrmT"))
1157 (const_int 0)) 1162 (const_int 0))
1158 (label_ref (match_operand 2 "" "")) 1163 (label_ref (match_operand 2 "" ""))
1159 (pc)))] 1164 (pc)))]
1160 "" 1165 ""
1161 "@ 1166 "@
1162 jlbs %0,%l2 1167 jlbs %0,%l2
1163 jbs %1,%0,%l2") 1168 jbs %1,%0,%l2")
1164 1169
1165(define_insn "" 1170(define_insn ""
1166 [(set (pc) 1171 [(set (pc)
1167 (if_then_else 1172 (if_then_else
1168 (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g") 1173 (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1169 (const_int 1) 1174 (const_int 1)
1170 (match_operand:SI 1 "general_operand" "I,nrmT")) 1175 (match_operand:SI 1 "general_operand" "I,nrmT"))
1171 (const_int 0)) 1176 (const_int 0))
1172 (label_ref (match_operand 2 "" "")) 1177 (label_ref (match_operand 2 "" ""))
1173 (pc)))] 1178 (pc)))]
1174 "" 1179 ""
1175 "@ 1180 "@
1176 jlbc %0,%l2 1181 jlbc %0,%l2
1177 jbc %1,%0,%l2") 1182 jbc %1,%0,%l2")
1178 1183
1179(define_insn "" 1184(define_insn ""
1180 [(set (pc) 1185 [(set (pc)
1181 (if_then_else 1186 (if_then_else
1182 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r") 1187 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1183 (const_int 1) 1188 (const_int 1)
1184 (match_operand:SI 1 "general_operand" "I,nrmT")) 1189 (match_operand:SI 1 "general_operand" "I,nrmT"))
1185 (const_int 0)) 1190 (const_int 0))
1186 (label_ref (match_operand 2 "" "")) 1191 (label_ref (match_operand 2 "" ""))
1187 (pc)))] 1192 (pc)))]
1188 "" 1193 ""
1189 "@ 1194 "@
1190 jlbs %0,%l2 1195 jlbs %0,%l2
1191 jbs %1,%0,%l2") 1196 jbs %1,%0,%l2")
1192 1197
1193(define_insn "" 1198(define_insn ""
1194 [(set (pc) 1199 [(set (pc)
1195 (if_then_else 1200 (if_then_else
1196 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r") 1201 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1197 (const_int 1) 1202 (const_int 1)
1198 (match_operand:SI 1 "general_operand" "I,nrmT")) 1203 (match_operand:SI 1 "general_operand" "I,nrmT"))
1199 (const_int 0)) 1204 (const_int 0))
1200 (label_ref (match_operand 2 "" "")) 1205 (label_ref (match_operand 2 "" ""))
1201 (pc)))] 1206 (pc)))]
1202 "" 1207 ""
1203 "@ 1208 "@
1204 jlbc %0,%l2 1209 jlbc %0,%l2
1205 jbc %1,%0,%l2") 1210 jbc %1,%0,%l2")
1206  1211
1207;; Subtract-and-jump and Add-and-jump insns. 1212;; Subtract-and-jump and Add-and-jump insns.
1208;; These are not used when output is for the Unix assembler 1213;; These are not used when output is for the Unix assembler
1209;; because it does not know how to modify them to reach far. 1214;; because it does not know how to modify them to reach far.
1210 1215
1211;; Normal sob insns. 1216;; Normal sob insns.
1212 1217
1213(define_insn "" 1218(define_insn ""
1214 [(set (pc) 1219 [(set (pc)
1215 (if_then_else 1220 (if_then_else
1216 (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") 1221 (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1217 (const_int -1)) 1222 (const_int -1))
1218 (const_int 0)) 1223 (const_int 0))
1219 (label_ref (match_operand 1 "" "")) 1224 (label_ref (match_operand 1 "" ""))
1220 (pc))) 1225 (pc)))
1221 (set (match_dup 0) 1226 (set (match_dup 0)
1222 (plus:SI (match_dup 0) 1227 (plus:SI (match_dup 0)
1223 (const_int -1)))] 1228 (const_int -1)))]
1224 "!TARGET_UNIX_ASM" 1229 "!TARGET_UNIX_ASM"
1225 "jsobgtr %0,%l1") 1230 "jsobgtr %0,%l1")
1226 1231
1227(define_insn "" 1232(define_insn ""
1228 [(set (pc) 1233 [(set (pc)
1229 (if_then_else 1234 (if_then_else
1230 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") 1235 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1231 (const_int -1)) 1236 (const_int -1))
1232 (const_int 0)) 1237 (const_int 0))
1233 (label_ref (match_operand 1 "" "")) 1238 (label_ref (match_operand 1 "" ""))
1234 (pc))) 1239 (pc)))
1235 (set (match_dup 0) 1240 (set (match_dup 0)
1236 (plus:SI (match_dup 0) 1241 (plus:SI (match_dup 0)
1237 (const_int -1)))] 1242 (const_int -1)))]
1238 "!TARGET_UNIX_ASM" 1243 "!TARGET_UNIX_ASM"
1239 "jsobgeq %0,%l1") 1244 "jsobgeq %0,%l1")
1240 1245
1241;; Normal aob insns. Define a version for when operands[1] is a constant. 1246;; Normal aob insns. Define a version for when operands[1] is a constant.
1242(define_insn "" 1247(define_insn ""
1243 [(set (pc) 1248 [(set (pc)
1244 (if_then_else 1249 (if_then_else
1245 (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") 1250 (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1246 (const_int 1)) 1251 (const_int 1))
1247 (match_operand:SI 1 "general_operand" "nrmT")) 1252 (match_operand:SI 1 "general_operand" "nrmT"))
1248 (label_ref (match_operand 2 "" "")) 1253 (label_ref (match_operand 2 "" ""))
1249 (pc))) 1254 (pc)))
1250 (set (match_dup 0) 1255 (set (match_dup 0)
1251 (plus:SI (match_dup 0) 1256 (plus:SI (match_dup 0)
1252 (const_int 1)))] 1257 (const_int 1)))]
1253 "!TARGET_UNIX_ASM" 1258 "!TARGET_UNIX_ASM"
1254 "jaoblss %1,%0,%l2") 1259 "jaoblss %1,%0,%l2")
1255 1260
1256(define_insn "" 1261(define_insn ""
1257 [(set (pc) 1262 [(set (pc)
1258 (if_then_else 1263 (if_then_else
1259 (lt (match_operand:SI 0 "nonimmediate_operand" "+g") 1264 (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
1260 (match_operand:SI 1 "general_operand" "nrmT")) 1265 (match_operand:SI 1 "general_operand" "nrmT"))
1261 (label_ref (match_operand 2 "" "")) 1266 (label_ref (match_operand 2 "" ""))
1262 (pc))) 1267 (pc)))
1263 (set (match_dup 0) 1268 (set (match_dup 0)
1264 (plus:SI (match_dup 0) 1269 (plus:SI (match_dup 0)
1265 (const_int 1)))] 1270 (const_int 1)))]
1266 "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])" 1271 "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1267 "jaoblss %P1,%0,%l2") 1272 "jaoblss %P1,%0,%l2")
1268 1273
1269(define_insn "" 1274(define_insn ""
1270 [(set (pc) 1275 [(set (pc)
1271 (if_then_else 1276 (if_then_else
1272 (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") 1277 (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1273 (const_int 1)) 1278 (const_int 1))
1274 (match_operand:SI 1 "general_operand" "nrmT")) 1279 (match_operand:SI 1 "general_operand" "nrmT"))
1275 (label_ref (match_operand 2 "" "")) 1280 (label_ref (match_operand 2 "" ""))
1276 (pc))) 1281 (pc)))
1277 (set (match_dup 0) 1282 (set (match_dup 0)
1278 (plus:SI (match_dup 0) 1283 (plus:SI (match_dup 0)
1279 (const_int 1)))] 1284 (const_int 1)))]
1280 "!TARGET_UNIX_ASM" 1285 "!TARGET_UNIX_ASM"
1281 "jaobleq %1,%0,%l2") 1286 "jaobleq %1,%0,%l2")
1282 1287
1283(define_insn "" 1288(define_insn ""
1284 [(set (pc) 1289 [(set (pc)
1285 (if_then_else 1290 (if_then_else
1286 (le (match_operand:SI 0 "nonimmediate_operand" "+g") 1291 (le (match_operand:SI 0 "nonimmediate_operand" "+g")
1287 (match_operand:SI 1 "general_operand" "nrmT")) 1292 (match_operand:SI 1 "general_operand" "nrmT"))
1288 (label_ref (match_operand 2 "" "")) 1293 (label_ref (match_operand 2 "" ""))
1289 (pc))) 1294 (pc)))
1290 (set (match_dup 0) 1295 (set (match_dup 0)
1291 (plus:SI (match_dup 0) 1296 (plus:SI (match_dup 0)
1292 (const_int 1)))] 1297 (const_int 1)))]
1293 "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])" 1298 "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1294 "jaobleq %P1,%0,%l2") 1299 "jaobleq %P1,%0,%l2")
1295 1300
1296;; Something like a sob insn, but compares against -1. 1301;; Something like a sob insn, but compares against -1.
1297;; This finds `while (foo--)' which was changed to `while (--foo != -1)'. 1302;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.
1298 1303
1299(define_insn "" 1304(define_insn ""
1300 [(set (pc) 1305 [(set (pc)
1301 (if_then_else 1306 (if_then_else
1302 (ne (match_operand:SI 0 "nonimmediate_operand" "+g") 1307 (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
1303 (const_int 0)) 1308 (const_int 0))
1304 (label_ref (match_operand 1 "" "")) 1309 (label_ref (match_operand 1 "" ""))
1305 (pc))) 1310 (pc)))
1306 (set (match_dup 0) 1311 (set (match_dup 0)
1307 (plus:SI (match_dup 0) 1312 (plus:SI (match_dup 0)
1308 (const_int -1)))] 1313 (const_int -1)))]
1309 "" 1314 ""
1310 "decl %0\;jgequ %l1") 1315 "decl %0\;jgequ %l1")
1311  1316
 1317;; Note that operand 1 is total size of args, in bytes,
 1318;; and what the call insn wants is the number of words.
 1319;; It is used in the call instruction as a byte, but in the addl2 as
 1320;; a word. Since the only time we actually use it in the call instruction
 1321;; is when it is a constant, SImode (for addl2) is the proper mode.
1312(define_expand "call_pop" 1322(define_expand "call_pop"
1313 [(parallel [(call (match_operand:QI 0 "memory_operand" "") 1323 [(parallel [(call (match_operand:QI 0 "memory_operand" "")
1314 (match_operand:SI 1 "const_int_operand" "")) 1324 (match_operand:SI 1 "const_int_operand" ""))
1315 (set (reg:SI VAX_SP_REGNUM) 1325 (set (reg:SI VAX_SP_REGNUM)
1316 (plus:SI (reg:SI VAX_SP_REGNUM) 1326 (plus:SI (reg:SI VAX_SP_REGNUM)
1317 (match_operand:SI 3 "immediate_operand" "")))])] 1327 (match_operand:SI 3 "immediate_operand" "")))])]
1318 "" 1328 ""
1319{ 1329{
1320 gcc_assert (INTVAL (operands[3]) <= 255 * 4 && INTVAL (operands[3]) % 4 == 0); 1330 gcc_assert (INTVAL (operands[1]) <= 255 * 4);
1321 1331 operands[1] = GEN_INT ((INTVAL (operands[1]) + 3) / 4);
1322 /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size 
1323 during EH unwinding. We must include the argument count pushed by 
1324 the calls instruction. */ 
1325 operands[1] = GEN_INT (INTVAL (operands[3]) + 4); 
1326}) 1332})
1327 1333
1328(define_insn "*call_pop" 1334(define_insn "*call_pop"
1329 [(call (match_operand:QI 0 "memory_operand" "m") 1335 [(call (match_operand:QI 0 "memory_operand" "m")
1330 (match_operand:SI 1 "const_int_operand" "n")) 1336 (match_operand:SI 1 "const_int_operand" "n"))
1331 (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM) 1337 (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1332 (match_operand:SI 2 "immediate_operand" "i")))] 1338 (match_operand:SI 2 "immediate_operand" "i")))]
1333 "" 1339 ""
1334{ 1340 "calls %1,%0")
1335 operands[1] = GEN_INT ((INTVAL (operands[1]) - 4) / 4); 
1336 return "calls %1,%0"; 
1337}) 
1338 1341
1339(define_expand "call_value_pop" 1342(define_expand "call_value_pop"
1340 [(parallel [(set (match_operand 0 "" "") 1343 [(parallel [(set (match_operand 0 "" "")
1341 (call (match_operand:QI 1 "memory_operand" "") 1344 (call (match_operand:QI 1 "memory_operand" "")
1342 (match_operand:SI 2 "const_int_operand" ""))) 1345 (match_operand:SI 2 "const_int_operand" "")))
1343 (set (reg:SI VAX_SP_REGNUM) 1346 (set (reg:SI VAX_SP_REGNUM)
1344 (plus:SI (reg:SI VAX_SP_REGNUM) 1347 (plus:SI (reg:SI VAX_SP_REGNUM)
1345 (match_operand:SI 4 "immediate_operand" "")))])] 1348 (match_operand:SI 4 "immediate_operand" "")))])]
1346 "" 1349 ""
1347{ 1350{
1348 gcc_assert (INTVAL (operands[4]) <= 255 * 4 && INTVAL (operands[4]) % 4 == 0); 1351 gcc_assert (INTVAL (operands[2]) <= 255 * 4);
1349 1352 operands[2] = GEN_INT ((INTVAL (operands[2]) + 3) / 4);
1350 /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size 
1351 during EH unwinding. We must include the argument count pushed by 
1352 the calls instruction. */ 
1353 operands[2] = GEN_INT (INTVAL (operands[4]) + 4); 
1354}) 1353})
1355 1354
1356(define_insn "*call_value_pop" 1355(define_insn "*call_value_pop"
1357 [(set (match_operand 0 "" "") 1356 [(set (match_operand 0 "" "")
1358 (call (match_operand:QI 1 "memory_operand" "m") 1357 (call (match_operand:QI 1 "memory_operand" "m")
1359 (match_operand:SI 2 "const_int_operand" "n"))) 1358 (match_operand:SI 2 "const_int_operand" "n")))
1360 (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM) 1359 (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1361 (match_operand:SI 3 "immediate_operand" "i")))] 1360 (match_operand:SI 3 "immediate_operand" "i")))]
1362 "" 1361 ""
1363 "* 1362 "calls %2,%1")
1364{ 
1365 operands[2] = GEN_INT ((INTVAL (operands[2]) - 4) / 4); 
1366 return \"calls %2,%1\"; 
1367}") 
1368 1363
1369(define_expand "call" 1364;; Define another set of these for the case of functions with no operands.
1370 [(call (match_operand:QI 0 "memory_operand" "") 1365;; These will allow the optimizers to do a slightly better job.
1371 (match_operand:SI 1 "const_int_operand" ""))] 1366(define_insn "call"
1372 "" 1367 [(call (match_operand:QI 0 "memory_operand" "m")
1373 " 1368 (const_int 0))]
1374{ 
1375 /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size 
1376 during EH unwinding. We must include the argument count pushed by 
1377 the calls instruction. */ 
1378 operands[1] = GEN_INT (INTVAL (operands[1]) + 4); 
1379}") 
1380 
1381(define_insn "*call" 
1382 [(call (match_operand:QI 0 "memory_operand" "m") 
1383 (match_operand:SI 1 "const_int_operand" ""))] 
1384 "" 1369 ""
1385 "calls $0,%0") 1370 "calls $0,%0")
1386 1371
1387(define_expand "call_value" 1372(define_insn "call_value"
1388 [(set (match_operand 0 "" "") 
1389 (call (match_operand:QI 1 "memory_operand" "") 
1390 (match_operand:SI 2 "const_int_operand" "")))] 
1391 "" 
1392 " 
1393{ 
1394 /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size 
1395 during EH unwinding. We must include the argument count pushed by 
1396 the calls instruction. */ 
1397 operands[2] = GEN_INT (INTVAL (operands[2]) + 4); 
1398}") 
1399 
1400(define_insn "*call_value" 
1401 [(set (match_operand 0 "" "") 1373 [(set (match_operand 0 "" "")
1402 (call (match_operand:QI 1 "memory_operand" "m") 1374 (call (match_operand:QI 1 "memory_operand" "m")
1403 (match_operand:SI 2 "const_int_operand" "")))] 1375 (const_int 0)))]
1404 "" 1376 ""
1405 "calls $0,%1") 1377 "calls $0,%1")
1406 1378
1407;; Call subroutine returning any type. 1379;; Call subroutine returning any type.
1408 1380
1409(define_expand "untyped_call" 1381(define_expand "untyped_call"
1410 [(parallel [(call (match_operand 0 "" "") 1382 [(parallel [(call (match_operand 0 "" "")
1411 (const_int 0)) 1383 (const_int 0))
1412 (match_operand 1 "" "") 1384 (match_operand 1 "" "")
1413 (match_operand 2 "" "")])] 1385 (match_operand 2 "" "")])]
1414 "" 1386 ""
1415 " 1387 "
1416{ 1388{
1417 int i; 1389 int i;
1418 1390
1419 emit_call_insn (gen_call_pop (operands[0], const0_rtx, NULL, const0_rtx)); 1391 emit_call_insn (gen_call_pop (operands[0], const0_rtx, NULL, const0_rtx));
1420 1392
1421 for (i = 0; i < XVECLEN (operands[2], 0); i++) 1393 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1422 { 1394 {
1423 rtx set = XVECEXP (operands[2], 0, i); 1395 rtx set = XVECEXP (operands[2], 0, i);
1424 emit_move_insn (SET_DEST (set), SET_SRC (set)); 1396 emit_move_insn (SET_DEST (set), SET_SRC (set));
1425 } 1397 }
1426 1398
1427 /* The optimizer does not know that the call sets the function value 1399 /* The optimizer does not know that the call sets the function value
1428 registers we stored in the result block. We avoid problems by 1400 registers we stored in the result block. We avoid problems by
1429 claiming that all hard registers are used and clobbered at this 1401 claiming that all hard registers are used and clobbered at this
1430 point. */ 1402 point. */
1431 emit_insn (gen_blockage ()); 1403 emit_insn (gen_blockage ());
1432 1404
1433 DONE; 1405 DONE;
1434}") 1406}")
1435 1407
1436;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 1408;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1437;; all of memory. This blocks insns from being moved across this point. 1409;; all of memory. This blocks insns from being moved across this point.
1438 1410
1439(define_insn "blockage" 1411(define_insn "blockage"
1440 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] 1412 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
1441 "" 1413 ""
1442 "") 1414 "")
1443 1415
1444(define_insn "procedure_entry_mask" 1416(define_insn "procedure_entry_mask"
1445 [(unspec_volatile [(match_operand 0 "const_int_operand")] VUNSPEC_PEM)] 1417 [(unspec_volatile [(match_operand 0 "const_int_operand")] VUNSPEC_PEM)]
1446 "" 1418 ""
1447 ".word %x0") 1419 ".word %x0")
1448 1420
1449(define_insn "return" 1421(define_insn "return"
1450 [(return)] 1422 [(return)]
1451 "" 1423 ""
1452 "ret") 1424 "ret")
1453 1425
1454(define_expand "prologue" 1426(define_expand "prologue"
1455 [(const_int 0)] 1427 [(const_int 0)]
1456 "" 1428 ""
1457{ 1429{
1458 vax_expand_prologue (); 1430 vax_expand_prologue ();
1459 DONE; 1431 DONE;
1460}) 1432})
1461 1433
1462(define_expand "epilogue" 1434(define_expand "epilogue"
1463 [(return)] 1435 [(return)]
1464 "" 1436 ""
1465 " 1437 "
1466{ 1438{
1467 emit_jump_insn (gen_return ()); 1439 emit_jump_insn (gen_return ());
1468 DONE; 1440 DONE;
1469}") 1441}")
1470 1442
1471(define_insn "nop" 1443(define_insn "nop"
1472 [(const_int 0)] 1444 [(const_int 0)]
1473 "" 1445 ""
1474 "nop") 1446 "nop")
1475 1447
1476;; This had a wider constraint once, and it had trouble. 1448;; This had a wider constraint once, and it had trouble.
1477;; If you are tempted to try `g', please don't--it's not worth 1449;; If you are tempted to try `g', please don't--it's not worth
1478;; the risk we will reopen the same bug. 1450;; the risk we will reopen the same bug.
1479(define_insn "indirect_jump" 1451(define_insn "indirect_jump"
1480 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 1452 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1481 "" 1453 ""
1482 "jmp (%0)") 1454 "jmp (%0)")
1483 1455
1484;; This is here to accept 5 arguments (as passed by expand_end_case) 1456;; This is here to accept 5 arguments (as passed by expand_end_case)
1485;; and pass the first 4 along to the casesi1 pattern that really does 1457;; and pass the first 4 along to the casesi1 pattern that really does
1486;; the actual casesi work. We emit a jump here to the default label 1458;; the actual casesi work. We emit a jump here to the default label
1487;; _before_ the casesi so that we can be sure that the casesi never 1459;; _before_ the casesi so that we can be sure that the casesi never
1488;; drops through. 1460;; drops through.
1489;; This is suboptimal perhaps, but so is much of the rest of this 1461;; This is suboptimal perhaps, but so is much of the rest of this
1490;; machine description. For what it's worth, HPPA uses the same trick. 1462;; machine description. For what it's worth, HPPA uses the same trick.
1491;; 1463;;
1492;; operand 0 is index 1464;; operand 0 is index
1493;; operand 1 is the minimum bound (a const_int) 1465;; operand 1 is the minimum bound (a const_int)
1494;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int) 1466;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int)
1495;; operand 3 is CODE_LABEL for the table; 1467;; operand 3 is CODE_LABEL for the table;
1496;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default). 1468;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default).
1497;; 1469;;
1498;; We emit: 1470;; We emit:
1499;; i = index - minimum_bound 1471;; i = index - minimum_bound
1500;; if (i > (maximum_bound - minimum_bound + 1) goto default; 1472;; if (i > (maximum_bound - minimum_bound + 1) goto default;
1501;; casesi (i, 0, table); 1473;; casesi (i, 0, table);
1502;; 1474;;
1503(define_expand "casesi" 1475(define_expand "casesi"
1504 [(match_operand:SI 0 "general_operand" "") 1476 [(match_operand:SI 0 "general_operand" "")
1505 (match_operand:SI 1 "general_operand" "") 1477 (match_operand:SI 1 "general_operand" "")
1506 (match_operand:SI 2 "general_operand" "") 1478 (match_operand:SI 2 "general_operand" "")
1507 (match_operand 3 "" "") 1479 (match_operand 3 "" "")
1508 (match_operand 4 "" "")] 1480 (match_operand 4 "" "")]
1509 "" 1481 ""
1510{ 1482{
1511 rtx test; 1483 rtx test;
1512 1484
1513 /* i = index - minimum_bound; 1485 /* i = index - minimum_bound;
1514 But only if the lower bound is not already zero. */ 1486 But only if the lower bound is not already zero. */
1515 if (operands[1] != const0_rtx) 1487 if (operands[1] != const0_rtx)
1516 { 1488 {
1517 rtx index = gen_reg_rtx (SImode); 1489 rtx index = gen_reg_rtx (SImode);
1518 emit_insn (gen_addsi3 (index, 1490 emit_insn (gen_addsi3 (index,
1519 operands[0], 1491 operands[0],
1520 GEN_INT (-INTVAL (operands[1])))); 1492 GEN_INT (-INTVAL (operands[1]))));
1521 operands[0] = index; 1493 operands[0] = index;
1522 } 1494 }
1523 1495
1524 /* if (i > (maximum_bound - minimum_bound + 1)) goto default; */ 1496 /* if (i > (maximum_bound - minimum_bound + 1)) goto default; */
1525 test = gen_rtx_fmt_ee (GTU, VOIDmode, operands[0], operands[2]); 1497 test = gen_rtx_fmt_ee (GTU, VOIDmode, operands[0], operands[2]);
1526 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4])); 1498 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
1527 1499
1528 /* casesi (i, 0, table); */ 1500 /* casesi (i, 0, table); */
1529 emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3])); 1501 emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3]));
1530 DONE; 1502 DONE;
1531}) 1503})
1532 1504
1533;; This insn is a bit of a lier. It actually falls through if no case 1505;; This insn is a bit of a lier. It actually falls through if no case
1534;; matches. But, we prevent that from ever happening by emitting a jump 1506;; matches. But, we prevent that from ever happening by emitting a jump
1535;; before this, see the define_expand above. 1507;; before this, see the define_expand above.
1536(define_insn "casesi1" 1508(define_insn "casesi1"
1537 [(match_operand:SI 1 "const_int_operand" "n") 1509 [(match_operand:SI 1 "const_int_operand" "n")
1538 (set (pc) 1510 (set (pc)
1539 (plus:SI (sign_extend:SI 1511 (plus:SI (sign_extend:SI
1540 (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT") 1512 (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT")
1541 (const_int 2)) 1513 (const_int 2))
1542 (pc)))) 1514 (pc))))
1543 (label_ref:SI (match_operand 2 "" ""))))] 1515 (label_ref:SI (match_operand 2 "" ""))))]
1544 "" 1516 ""
1545 "casel %0,$0,%1") 1517 "casel %0,$0,%1")
1546  1518
1547(define_insn "pushextsym" 1519(define_insn "pushextsym"
1548 [(set (match_operand:SI 0 "push_operand" "=g") 1520 [(set (match_operand:SI 0 "push_operand" "=g")
1549 (match_operand:SI 1 "external_symbolic_operand" "i"))] 1521 (match_operand:SI 1 "external_symbolic_operand" "i"))]
1550 "" 1522 ""
1551 "pushab %a1") 1523 "pushab %a1")
1552 1524
1553(define_insn "movextsym" 1525(define_insn "movextsym"
1554 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 1526 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1555 (match_operand:SI 1 "external_symbolic_operand" "i"))] 1527 (match_operand:SI 1 "external_symbolic_operand" "i"))]
1556 "" 1528 ""
1557 "movab %a1,%0") 1529 "movab %a1,%0")
1558 1530
1559(define_insn "pushlclsym" 1531(define_insn "pushlclsym"
1560 [(set (match_operand:SI 0 "push_operand" "=g") 1532 [(set (match_operand:SI 0 "push_operand" "=g")
1561 (match_operand:SI 1 "local_symbolic_operand" "i"))] 1533 (match_operand:SI 1 "local_symbolic_operand" "i"))]
1562 "" 1534 ""
1563 "pushab %a1") 1535 "pushab %a1")
1564 1536
1565(define_insn "movlclsym" 1537(define_insn "movlclsym"
1566 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 1538 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1567 (match_operand:SI 1 "local_symbolic_operand" "i"))] 1539 (match_operand:SI 1 "local_symbolic_operand" "i"))]
1568 "" 1540 ""
1569 "movab %a1,%0") 1541 "movab %a1,%0")
1570  1542
1571;;- load or push effective address 1543;;- load or push effective address
1572;; These come after the move and add/sub patterns 1544;; These come after the move and add/sub patterns
1573;; because we don't want pushl $1 turned into pushad 1. 1545;; because we don't want pushl $1 turned into pushad 1.
1574;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3. 1546;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3.
1575 1547
1576;; It does not work to use constraints to distinguish pushes from moves, 1548;; It does not work to use constraints to distinguish pushes from moves,
1577;; because < matches any autodecrement, not just a push. 1549;; because < matches any autodecrement, not just a push.
1578 1550
1579(define_insn "pushaddr<mode>" 1551(define_insn "pushaddr<mode>"
1580 [(set (match_operand:SI 0 "push_operand" "=g") 1552 [(set (match_operand:SI 0 "push_operand" "=g")
1581 (match_operand:VAXintQHSD 1 "address_operand" "p"))] 1553 (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1582 "" 1554 ""
1583 "pusha<VAXintQHSD:isfx> %a1") 1555 "pusha<VAXintQHSD:isfx> %a1")
1584 1556
1585(define_insn "movaddr<mode>" 1557(define_insn "movaddr<mode>"
1586 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 1558 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1587 (match_operand:VAXintQHSD 1 "address_operand" "p"))] 1559 (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1588 "" 1560 ""
1589 "mova<VAXintQHSD:isfx> %a1,%0") 1561 "mova<VAXintQHSD:isfx> %a1,%0")
1590 1562
1591(define_insn "pushaddr<mode>" 1563(define_insn "pushaddr<mode>"
1592 [(set (match_operand:SI 0 "push_operand" "=g") 1564 [(set (match_operand:SI 0 "push_operand" "=g")
1593 (match_operand:VAXfp 1 "address_operand" "p"))] 1565 (match_operand:VAXfp 1 "address_operand" "p"))]
1594 "" 1566 ""
1595 "pusha<VAXfp:fsfx> %a1") 1567 "pusha<VAXfp:fsfx> %a1")
1596 1568
1597(define_insn "movaddr<mode>" 1569(define_insn "movaddr<mode>"
1598 [(set (match_operand:SI 0 "nonimmediate_operand" "=g") 1570 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1599 (match_operand:VAXfp 1 "address_operand" "p"))] 1571 (match_operand:VAXfp 1 "address_operand" "p"))]
1600 "" 1572 ""
1601 "mova<VAXfp:fsfx> %a1,%0") 1573 "mova<VAXfp:fsfx> %a1,%0")
1602  1574
1603;; These used to be peepholes, but it is more straightforward to do them 1575;; These used to be peepholes, but it is more straightforward to do them
1604;; as single insns. However, we must force the output to be a register 1576;; as single insns. However, we must force the output to be a register
1605;; if it is not an offsettable address so that we know that we can assign 1577;; if it is not an offsettable address so that we know that we can assign
1606;; to it twice. 1578;; to it twice.
1607 1579
1608;; If we had a good way of evaluating the relative costs, these could be 1580;; If we had a good way of evaluating the relative costs, these could be
1609;; machine-independent. 1581;; machine-independent.
1610 1582
1611;; Optimize extzv ...,z; andl2 ...,z 1583;; Optimize extzv ...,z; andl2 ...,z
1612;; or ashl ...,z; andl2 ...,z 1584;; or ashl ...,z; andl2 ...,z
1613;; with other operands constant. This is what the combiner converts the 1585;; with other operands constant. This is what the combiner converts the
1614;; above sequences to before attempting to recognize the new insn. 1586;; above sequences to before attempting to recognize the new insn.
1615 1587
1616(define_insn "" 1588(define_insn ""
1617 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") 1589 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1618 (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") 1590 (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
1619 (match_operand:QI 2 "const_int_operand" "n")) 1591 (match_operand:QI 2 "const_int_operand" "n"))
1620 (match_operand:SI 3 "const_int_operand" "n")))] 1592 (match_operand:SI 3 "const_int_operand" "n")))]
1621 "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0" 1593 "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0"
1622 "* 1594 "*
1623{ 1595{
1624 unsigned long mask1 = INTVAL (operands[3]); 1596 unsigned long mask1 = INTVAL (operands[3]);
1625 unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1; 1597 unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1;
1626 1598
1627 if ((mask1 & mask2) != mask1) 1599 if ((mask1 & mask2) != mask1)
1628 operands[3] = GEN_INT (mask1 & mask2); 1600 operands[3] = GEN_INT (mask1 & mask2);
1629 1601
1630 return \"rotl %R2,%1,%0\;bicl2 %N3,%0\"; 1602 return \"rotl %R2,%1,%0\;bicl2 %N3,%0\";
1631}") 1603}")
1632 1604
1633;; left-shift and mask 1605;; left-shift and mask
1634;; The only case where `ashl' is better is if the mask only turns off 1606;; The only case where `ashl' is better is if the mask only turns off
1635;; bits that the ashl would anyways, in which case it should have been 1607;; bits that the ashl would anyways, in which case it should have been
1636;; optimized away. 1608;; optimized away.
1637 1609
1638(define_insn "" 1610(define_insn ""
1639 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") 1611 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1640 (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") 1612 (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
1641 (match_operand:QI 2 "const_int_operand" "n")) 1613 (match_operand:QI 2 "const_int_operand" "n"))
1642 (match_operand:SI 3 "const_int_operand" "n")))] 1614 (match_operand:SI 3 "const_int_operand" "n")))]
1643 "" 1615 ""
1644 "* 1616 "*
1645{ 1617{
1646 operands[3] 1618 operands[3]
1647 = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1)); 1619 = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1));
1648 return \"rotl %2,%1,%0\;bicl2 %N3,%0\"; 1620 return \"rotl %2,%1,%0\;bicl2 %N3,%0\";
1649}") 1621}")
1650 1622
1651;; Instruction sequence to sync the VAX instruction stream. 1623;; Instruction sequence to sync the VAX instruction stream.
1652(define_insn "sync_istream" 1624(define_insn "sync_istream"
1653 [(unspec_volatile [(const_int 0)] VUNSPEC_SYNC_ISTREAM)] 1625 [(unspec_volatile [(const_int 0)] VUNSPEC_SYNC_ISTREAM)]
1654 "" 1626 ""
1655 "movpsl -(%|sp)\;pushal 1(%|pc)\;rei") 1627 "movpsl -(%|sp)\;pushal 1(%|pc)\;rei")
1656 1628
1657(define_expand "nonlocal_goto" 1629(define_expand "nonlocal_goto"
1658 [(use (match_operand 0 "general_operand" "")) 1630 [(use (match_operand 0 "general_operand" ""))
1659 (use (match_operand 1 "general_operand" "")) 1631 (use (match_operand 1 "general_operand" ""))
1660 (use (match_operand 2 "general_operand" "")) 1632 (use (match_operand 2 "general_operand" ""))
1661 (use (match_operand 3 "general_operand" ""))] 1633 (use (match_operand 3 "general_operand" ""))]
1662 "" 1634 ""
1663{ 1635{
1664 rtx lab = operands[1]; 1636 rtx lab = operands[1];
1665 rtx stack = operands[2]; 1637 rtx stack = operands[2];
1666 rtx fp = operands[3]; 1638 rtx fp = operands[3];
1667 1639
1668 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); 1640 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1669 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); 1641 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1670 1642
1671 emit_move_insn (hard_frame_pointer_rtx, fp); 1643 emit_move_insn (hard_frame_pointer_rtx, fp);
1672 emit_stack_restore (SAVE_NONLOCAL, stack); 1644 emit_stack_restore (SAVE_NONLOCAL, stack);
1673 1645
1674 emit_use (hard_frame_pointer_rtx); 1646 emit_use (hard_frame_pointer_rtx);
1675 emit_use (stack_pointer_rtx); 1647 emit_use (stack_pointer_rtx);
1676 1648
1677 /* We'll convert this to direct jump via a peephole optimization. */ 1649 /* We'll convert this to direct jump via a peephole optimization. */
1678 emit_indirect_jump (copy_to_reg (lab)); 1650 emit_indirect_jump (copy_to_reg (lab));
1679 emit_barrier (); 1651 emit_barrier ();
1680 DONE; 1652 DONE;
1681}) 1653})
1682 1654
1683(include "builtins.md") 1655(include "builtins.md")
1684 1656
1685(define_peephole2 1657(define_peephole2
1686 [(set (match_operand:SI 0 "push_operand" "") 1658 [(set (match_operand:SI 0 "push_operand" "")
1687 (const_int 0)) 1659 (const_int 0))
1688 (set (match_dup 0) 1660 (set (match_dup 0)
1689 (match_operand:SI 1 "const_int_operand" ""))] 1661 (match_operand:SI 1 "const_int_operand" ""))]
1690 "INTVAL (operands[1]) >= 0" 1662 "INTVAL (operands[1]) >= 0"
1691 [(set (match_dup 0) 1663 [(set (match_dup 0)
1692 (match_dup 1))] 1664 (match_dup 1))]
1693 "operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));") 1665 "operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));")
1694 1666
1695(define_peephole2 1667(define_peephole2
1696 [(set (match_operand:SI 0 "push_operand" "") 1668 [(set (match_operand:SI 0 "push_operand" "")
1697 (match_operand:SI 1 "general_operand" "")) 1669 (match_operand:SI 1 "general_operand" ""))
1698 (set (match_dup 0) 1670 (set (match_dup 0)
1699 (match_operand:SI 2 "general_operand" ""))] 1671 (match_operand:SI 2 "general_operand" ""))]
1700 "vax_decomposed_dimode_operand_p (operands[2], operands[1])" 1672 "vax_decomposed_dimode_operand_p (operands[2], operands[1])"
1701 [(set (match_dup 0) 1673 [(set (match_dup 0)
1702 (match_dup 2))] 1674 (match_dup 2))]
1703 "{ 1675 "{
1704 operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0)); 1676 operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));
1705 operands[2] = REG_P (operands[2]) 1677 operands[2] = REG_P (operands[2])
1706 ? gen_rtx_REG(DImode, REGNO (operands[2])) 1678 ? gen_rtx_REG(DImode, REGNO (operands[2]))
1707 : gen_rtx_MEM(DImode, XEXP (operands[2], 0)); 1679 : gen_rtx_MEM(DImode, XEXP (operands[2], 0));
1708}") 1680}")
1709 1681
1710; Leave this commented out until we can determine whether the second move 1682; Leave this commented out until we can determine whether the second move
1711; precedes a jump which relies on the CC flags being set correctly. 1683; precedes a jump which relies on the CC flags being set correctly.
1712(define_peephole2 1684(define_peephole2
1713 [(set (match_operand:SI 0 "nonimmediate_operand" "") 1685 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1714 (match_operand:SI 1 "general_operand" "")) 1686 (match_operand:SI 1 "general_operand" ""))
1715 (set (match_operand:SI 2 "nonimmediate_operand" "") 1687 (set (match_operand:SI 2 "nonimmediate_operand" "")
1716 (match_operand:SI 3 "general_operand" ""))] 1688 (match_operand:SI 3 "general_operand" ""))]
1717 "0 && vax_decomposed_dimode_operand_p (operands[1], operands[3]) 1689 "0 && vax_decomposed_dimode_operand_p (operands[1], operands[3])
1718 && vax_decomposed_dimode_operand_p (operands[0], operands[2])" 1690 && vax_decomposed_dimode_operand_p (operands[0], operands[2])"
1719 [(set (match_dup 0) 1691 [(set (match_dup 0)
1720 (match_dup 1))] 1692 (match_dup 1))]
1721 "{ 1693 "{
1722 operands[0] = REG_P (operands[0]) 1694 operands[0] = REG_P (operands[0])
1723 ? gen_rtx_REG(DImode, REGNO (operands[0])) 1695 ? gen_rtx_REG(DImode, REGNO (operands[0]))
1724 : gen_rtx_MEM(DImode, XEXP (operands[0], 0)); 1696 : gen_rtx_MEM(DImode, XEXP (operands[0], 0));
1725 operands[1] = REG_P (operands[1]) 1697 operands[1] = REG_P (operands[1])
1726 ? gen_rtx_REG(DImode, REGNO (operands[1])) 1698 ? gen_rtx_REG(DImode, REGNO (operands[1]))
1727 : gen_rtx_MEM(DImode, XEXP (operands[1], 0)); 1699 : gen_rtx_MEM(DImode, XEXP (operands[1], 0));
1728}") 1700}")