In my backend GCC generates illegal scheduled code. After pass sched2, GCC generates:
;; 0--> 486 R1=R3<<0x4 :IF,ID,AD,RA,EX,WB ;; 1--> 487 A0=R1+`buffer' :IF,ID,AD,RA,EX,WB ;; 2--> 766 R0=abs(R7) :IF,ID,AD,RA,EX,WB ;; 3--> 456 STATUS=cmp(R3,0x0) :IF,ID,AD,RA,EX,WB ;; 4--> 767 R0=R0-0x1 :IF,ID,AD,RA,EX,WB ;; 5--> 465 (!STATUS) [A6]=R7^0x1 :IF,ID,AD,RA,EX,(WB+one_memory_port) ;; 6--> 469 R6=R6-R2 :IF,ID,AD,RA,EX,WB ;; 7--> 476 R7=R0 0>>0x1f :IF,ID,AD,RA,EX,WB ;; 9--> 488 [A4]=zxn([A0]) :IF,ID,(AD+two_memory_ports),RA,EX,(WB+two_memory_ports) ;; 10--> 925 pc=L489 :IF,ID,AD,RA,EX,WB The instructions 465 and 488 have a pipeline hazard, because they need 3 memory ports at some time, but there are only two ports. The unit reservation templates are: (define_reservation "one_memory_port" "(MP1 | MP2)") (define_reservation "two_memory_ports" "(MP1 + MP2)") I checked my scheduler description, and I can't find an error. For GCC this hazard is ok, because GCC assumes the processor can stall the pipeline. But after branch-delay-slots filling the code is: (insn 1001 767 1002 (sequence [ (jump_insn 941 767 465 (set (pc) (label_ref 489)) 119 {jump_to_immediate_long} (nil) (expr_list:REG_BR_PRED (const_int 14 [0xe]) (nil))) (insn:HI 465 941 469 (cond_exec (eq (reg:CC 48 STATUS) (const_int 0 [0x0])) (set (mem/s:SI (reg/f:SI 38 A6 [479]) [4 <variable>.MPS+0 S32 A32]) (xor:SI (reg/v:SI 7 R7 [orig:125 bit ] [125]) (const_int 1 [0x1])))) 205 {doloop_end+31} (nil) (nil)) (insn:HI 469 465 476 (set (reg/v:SI 6 R6 [orig:124 value ] [124]) (minus:SI (reg/v:SI 6 R6 [orig:124 value ] [124]) (reg/v:SI 2 R2 [orig:107 0xa60range ] [107]))) 30 {subsi3_register_internal} (nil) (nil)) (insn:HI 476 469 488 (set (reg/v:SI 7 R7 [orig:125 bit ] [125]) (lshiftrt:SI (reg:SI 0 R0 [473]) (const_int 31 [0x1f]))) 75 {lshrsi3_const5bit} (nil) (nil)) (insn:HI 488 476 1002 (set (mem/s:SI (reg/f:SI 36 A4 [478]) [4 <variable>.state+0 S32 A32]) (zero_extend:SI (mem/s/u:HI (reg/f:SI 32 A0 [365]) [17 buffer S16 A16]))) 102 {zero_extendhisi2} (nil) (nil)) ]) -1 (nil) (nil)) The four instructions before the jump are placed into the delay slots, such that the delay slots are completely filled; but there is still the pipeline hazard, which can't be resolved by inserting NOPs now, because there are no free slots. Do I have to reorganize the code prior to slot filling? Do I have to make sure that some problematic instructions do not appear in slots? Boris