1.1 --- a/src/cpu/mips/vm/mips_64.ad Wed Aug 02 13:34:23 2017 +0800 1.2 +++ b/src/cpu/mips/vm/mips_64.ad Thu Aug 03 16:06:12 2017 +0800 1.3 @@ -7550,6 +7550,80 @@ 1.4 ins_pipe( pipe_alu_branch ); 1.5 %} 1.6 1.7 +instruct branchConL_regL_immL(cmpOp cmp, mRegL src1, immL src2, label labl) %{ 1.8 + match( If cmp (CmpL src1 src2) ); 1.9 + effect(USE labl); 1.10 + format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_immL" %} 1.11 + ins_cost(180); 1.12 + 1.13 + ins_encode %{ 1.14 + Register opr1_reg = as_Register($src1$$reg); 1.15 + Register opr2_reg = AT; 1.16 + 1.17 + Label &target = *($labl$$label); 1.18 + int flag = $cmp$$cmpcode; 1.19 + 1.20 + __ set64(opr2_reg, $src2$$constant); 1.21 + 1.22 + switch(flag) 1.23 + { 1.24 + case 0x01: //equal 1.25 + if (&target) 1.26 + __ beq(opr1_reg, opr2_reg, target); 1.27 + else 1.28 + __ beq(opr1_reg, opr2_reg, (int)0); 1.29 + break; 1.30 + 1.31 + case 0x02: //not_equal 1.32 + if(&target) 1.33 + __ bne(opr1_reg, opr2_reg, target); 1.34 + else 1.35 + __ bne(opr1_reg, opr2_reg, (int)0); 1.36 + break; 1.37 + 1.38 + case 0x03: //greater 1.39 + __ slt(AT, opr2_reg, opr1_reg); 1.40 + if(&target) 1.41 + __ bne(AT, R0, target); 1.42 + else 1.43 + __ bne(AT, R0, (int)0); 1.44 + break; 1.45 + 1.46 + case 0x04: //greater_equal 1.47 + __ slt(AT, opr1_reg, opr2_reg); 1.48 + if(&target) 1.49 + __ beq(AT, R0, target); 1.50 + else 1.51 + __ beq(AT, R0, (int)0); 1.52 + break; 1.53 + 1.54 + case 0x05: //less 1.55 + __ slt(AT, opr1_reg, opr2_reg); 1.56 + if(&target) 1.57 + __ bne(AT, R0, target); 1.58 + else 1.59 + __ bne(AT, R0, (int)0); 1.60 + break; 1.61 + 1.62 + case 0x06: //less_equal 1.63 + __ slt(AT, opr2_reg, opr1_reg); 1.64 + if(&target) 1.65 + __ beq(AT, R0, target); 1.66 + else 1.67 + __ beq(AT, R0, (int)0); 1.68 + break; 1.69 + 1.70 + default: 1.71 + Unimplemented(); 1.72 + } 1.73 + __ nop(); 1.74 + %} 1.75 + 1.76 + 1.77 + ins_pc_relative(1); 1.78 + ins_pipe( pipe_alu_branch ); 1.79 +%} 1.80 + 1.81 1.82 //FIXME 1.83 instruct branchConF_reg_reg(cmpOp cmp, regF src1, regF src2, label labl) %{ 1.84 @@ -12681,6 +12755,71 @@ 1.85 ins_pc_relative(1); 1.86 %} 1.87 1.88 +instruct jmpLoopEnd_reg_immI(cmpOp cop, mRegI src1, immI src2, label labl) %{ 1.89 + match(CountedLoopEnd cop (CmpI src1 src2)); 1.90 + effect(USE labl); 1.91 + 1.92 + ins_cost(300); 1.93 + format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_immI" %} 1.94 + ins_encode %{ 1.95 + Register op1 = $src1$$Register; 1.96 + Register op2 = AT; 1.97 + Label &L = *($labl$$label); 1.98 + int flag = $cop$$cmpcode; 1.99 + 1.100 + __ move(op2, $src2$$constant); 1.101 + 1.102 + switch(flag) 1.103 + { 1.104 + case 0x01: //equal 1.105 + if (&L) 1.106 + __ beq(op1, op2, L); 1.107 + else 1.108 + __ beq(op1, op2, (int)0); 1.109 + break; 1.110 + case 0x02: //not_equal 1.111 + if (&L) 1.112 + __ bne(op1, op2, L); 1.113 + else 1.114 + __ bne(op1, op2, (int)0); 1.115 + break; 1.116 + case 0x03: //above 1.117 + __ slt(AT, op2, op1); 1.118 + if(&L) 1.119 + __ bne(AT, R0, L); 1.120 + else 1.121 + __ bne(AT, R0, (int)0); 1.122 + break; 1.123 + case 0x04: //above_equal 1.124 + __ slt(AT, op1, op2); 1.125 + if(&L) 1.126 + __ beq(AT, R0, L); 1.127 + else 1.128 + __ beq(AT, R0, (int)0); 1.129 + break; 1.130 + case 0x05: //below 1.131 + __ slt(AT, op1, op2); 1.132 + if(&L) 1.133 + __ bne(AT, R0, L); 1.134 + else 1.135 + __ bne(AT, R0, (int)0); 1.136 + break; 1.137 + case 0x06: //below_equal 1.138 + __ slt(AT, op2, op1); 1.139 + if(&L) 1.140 + __ beq(AT, R0, L); 1.141 + else 1.142 + __ beq(AT, R0, (int)0); 1.143 + break; 1.144 + default: 1.145 + Unimplemented(); 1.146 + } 1.147 + __ nop(); 1.148 + %} 1.149 + ins_pipe( pipe_jump ); 1.150 + ins_pc_relative(1); 1.151 +%} 1.152 + 1.153 1.154 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17 1.155 instruct jmpCon_flags(cmpOp cop, FlagsReg cr, label labl) %{