@@ -646,8 +646,8 @@ arc_sched_issue_rate (void)
646
646
{
647
647
switch (arc_tune)
648
648
{
649
- case TUNE_ARCHS4X :
650
- case TUNE_ARCHS4XD :
649
+ case ARC_TUNE_ARCHS4X :
650
+ case ARC_TUNE_ARCHS4XD :
651
651
return 3 ;
652
652
default :
653
653
break ;
@@ -1458,6 +1458,12 @@ arc_override_options (void)
1458
1458
if (!OPTION_SET_P (unaligned_access) && TARGET_HS)
1459
1459
unaligned_access = 1 ;
1460
1460
1461
+ if (TARGET_HS && (arc_tune == ARC_TUNE_ARCHS4X_REL31A))
1462
+ {
1463
+ TARGET_CODE_DENSITY_FRAME = 0 ;
1464
+ flag_delayed_branch = 0 ;
1465
+ }
1466
+
1461
1467
/* These need to be done at start up. It's convenient to do them here. */
1462
1468
arc_init ();
1463
1469
}
@@ -7817,6 +7823,115 @@ arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
7817
7823
return arc_store_addr_hazard_internal_p (producer, consumer);
7818
7824
}
7819
7825
7826
+ /* Return length adjustment for INSN.
7827
+ For ARC600:
7828
+ A write to a core reg greater or equal to 32 must not be immediately
7829
+ followed by a use. Anticipate the length requirement to insert a nop
7830
+ between PRED and SUCC to prevent a hazard. */
7831
+
7832
+ static int
7833
+ arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
7834
+ {
7835
+ if (!TARGET_ARC600)
7836
+ return 0 ;
7837
+ if (GET_CODE (PATTERN (pred)) == SEQUENCE)
7838
+ pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1 );
7839
+ if (GET_CODE (PATTERN (succ)) == SEQUENCE)
7840
+ succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0 );
7841
+ if (recog_memoized (pred) == CODE_FOR_mulsi_600
7842
+ || recog_memoized (pred) == CODE_FOR_umul_600
7843
+ || recog_memoized (pred) == CODE_FOR_mac_600
7844
+ || recog_memoized (pred) == CODE_FOR_mul64_600
7845
+ || recog_memoized (pred) == CODE_FOR_mac64_600
7846
+ || recog_memoized (pred) == CODE_FOR_umul64_600
7847
+ || recog_memoized (pred) == CODE_FOR_umac64_600)
7848
+ return 0 ;
7849
+ subrtx_iterator::array_type array;
7850
+ FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
7851
+ {
7852
+ const_rtx x = *iter;
7853
+ switch (GET_CODE (x))
7854
+ {
7855
+ case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
7856
+ break ;
7857
+ default :
7858
+ /* This is also fine for PRE/POST_MODIFY, because they
7859
+ contain a SET. */
7860
+ continue ;
7861
+ }
7862
+ rtx dest = XEXP (x, 0 );
7863
+ /* Check if this sets a an extension register. N.B. we use 61 for the
7864
+ condition codes, which is definitely not an extension register. */
7865
+ if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
7866
+ /* Check if the same register is used by the PAT. */
7867
+ && (refers_to_regno_p
7868
+ (REGNO (dest),
7869
+ REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3 ) / 4U ,
7870
+ PATTERN (succ), 0 )))
7871
+ return 4 ;
7872
+ }
7873
+ return 0 ;
7874
+ }
7875
+
7876
+ /* For ARC600:
7877
+ A write to a core reg greater or equal to 32 must not be immediately
7878
+ followed by a use. Anticipate the length requirement to insert a nop
7879
+ between PRED and SUCC to prevent a hazard. */
7880
+
7881
+ int
7882
+ arc_hazard (rtx_insn *pred, rtx_insn *succ)
7883
+ {
7884
+ if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7885
+ return 0 ;
7886
+
7887
+ if (TARGET_ARC600)
7888
+ return arc600_corereg_hazard (pred, succ);
7889
+
7890
+ return 0 ;
7891
+ }
7892
+
7893
+ /* When compiling for release 310a, insert a nop before any
7894
+ conditional jump. */
7895
+
7896
+ static int
7897
+ arc_check_release31a (rtx_insn *pred, rtx_insn *succ)
7898
+ {
7899
+ if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7900
+ return 0 ;
7901
+
7902
+ if (!JUMP_P (pred) && !single_set (pred))
7903
+ return 0 ;
7904
+
7905
+ if (!JUMP_P (succ) && !single_set (succ))
7906
+ return 0 ;
7907
+
7908
+ if (TARGET_HS && (arc_tune == ARC_TUNE_ARCHS4X_REL31A))
7909
+ switch (get_attr_type (pred))
7910
+ {
7911
+ case TYPE_STORE:
7912
+ switch (get_attr_type (succ))
7913
+ {
7914
+ case TYPE_BRCC:
7915
+ case TYPE_BRCC_NO_DELAY_SLOT:
7916
+ case TYPE_LOOP_END:
7917
+ return 1 ;
7918
+ default :
7919
+ break ;
7920
+ }
7921
+ break ;
7922
+ case TYPE_BRCC:
7923
+ case TYPE_BRCC_NO_DELAY_SLOT:
7924
+ case TYPE_LOOP_END:
7925
+ if (get_attr_type (succ) == TYPE_STORE)
7926
+ return 1 ;
7927
+ break ;
7928
+ default :
7929
+ break ;
7930
+ }
7931
+
7932
+ return 0 ;
7933
+ }
7934
+
7820
7935
/* The same functionality as arc_hazard. It is called in machine
7821
7936
reorg before any other optimization. Hence, the NOP size is taken
7822
7937
into account when doing branch shortening. */
@@ -7830,10 +7945,8 @@ workaround_arc_anomaly (void)
7830
7945
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7831
7946
{
7832
7947
succ0 = next_real_insn (insn);
7833
- if (arc_hazard (insn, succ0))
7834
- {
7835
- emit_insn_before (gen_nopv (), succ0);
7836
- }
7948
+ if (arc_hazard (insn, succ0) || arc_check_release31a (insn, succ0))
7949
+ emit_insn_before (gen_nopv (), succ0);
7837
7950
}
7838
7951
7839
7952
if (!TARGET_ARC700)
@@ -9324,56 +9437,6 @@ disi_highpart (rtx in)
9324
9437
return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4 );
9325
9438
}
9326
9439
9327
- /* Return length adjustment for INSN.
9328
- For ARC600:
9329
- A write to a core reg greater or equal to 32 must not be immediately
9330
- followed by a use. Anticipate the length requirement to insert a nop
9331
- between PRED and SUCC to prevent a hazard. */
9332
-
9333
- static int
9334
- arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
9335
- {
9336
- if (!TARGET_ARC600)
9337
- return 0 ;
9338
- if (GET_CODE (PATTERN (pred)) == SEQUENCE)
9339
- pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1 );
9340
- if (GET_CODE (PATTERN (succ)) == SEQUENCE)
9341
- succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0 );
9342
- if (recog_memoized (pred) == CODE_FOR_mulsi_600
9343
- || recog_memoized (pred) == CODE_FOR_umul_600
9344
- || recog_memoized (pred) == CODE_FOR_mac_600
9345
- || recog_memoized (pred) == CODE_FOR_mul64_600
9346
- || recog_memoized (pred) == CODE_FOR_mac64_600
9347
- || recog_memoized (pred) == CODE_FOR_umul64_600
9348
- || recog_memoized (pred) == CODE_FOR_umac64_600)
9349
- return 0 ;
9350
- subrtx_iterator::array_type array;
9351
- FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
9352
- {
9353
- const_rtx x = *iter;
9354
- switch (GET_CODE (x))
9355
- {
9356
- case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9357
- break ;
9358
- default :
9359
- /* This is also fine for PRE/POST_MODIFY, because they
9360
- contain a SET. */
9361
- continue ;
9362
- }
9363
- rtx dest = XEXP (x, 0 );
9364
- /* Check if this sets an extension register. N.B. we use 61 for the
9365
- condition codes, which is definitely not an extension register. */
9366
- if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
9367
- /* Check if the same register is used by the PAT. */
9368
- && (refers_to_regno_p
9369
- (REGNO (dest),
9370
- REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3 ) / 4U ,
9371
- PATTERN (succ), 0 )))
9372
- return 4 ;
9373
- }
9374
- return 0 ;
9375
- }
9376
-
9377
9440
/* Given a rtx, check if it is an assembly instruction or not. */
9378
9441
9379
9442
static int
@@ -9408,23 +9471,6 @@ arc_asm_insn_p (rtx x)
9408
9471
return 0 ;
9409
9472
}
9410
9473
9411
- /* For ARC600:
9412
- A write to a core reg greater or equal to 32 must not be immediately
9413
- followed by a use. Anticipate the length requirement to insert a nop
9414
- between PRED and SUCC to prevent a hazard. */
9415
-
9416
- int
9417
- arc_hazard (rtx_insn *pred, rtx_insn *succ)
9418
- {
9419
- if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
9420
- return 0 ;
9421
-
9422
- if (TARGET_ARC600)
9423
- return arc600_corereg_hazard (pred, succ);
9424
-
9425
- return 0 ;
9426
- }
9427
-
9428
9474
/* Return length adjustment for INSN. */
9429
9475
9430
9476
int
0 commit comments