@@ -38,6 +38,11 @@ macro_rules! debug_assert_valid_regpair {
3838 } ;
3939}
4040
41+ const OPCODE_BRAS : u16 = 0xa75 ;
42+ const OPCODE_BCR : u16 = 0xa74 ;
43+ const OPCODE_LDR : u16 = 0x28 ;
44+ const OPCODE_VLR : u16 = 0xe756 ;
45+
4146/// Type(s) of memory instructions available for mem_finalize.
4247pub struct MemInstType {
4348 /// True if 12-bit unsigned displacement is supported.
@@ -2298,9 +2303,8 @@ impl Inst {
22982303 rd,
22992304 ref symbol_reloc,
23002305 } => {
2301- let opcode = 0xa75 ; // BRAS
23022306 let reg = writable_spilltmp_reg ( ) . to_reg ( ) ;
2303- put ( sink, & enc_ri_b ( opcode , reg, 12 ) ) ;
2307+ put ( sink, & enc_ri_b ( OPCODE_BRAS , reg, 12 ) ) ;
23042308 let ( reloc, name, offset) = match & * * symbol_reloc {
23052309 SymbolReloc :: Absolute { name, offset } => ( Reloc :: Abs8 , name, * offset) ,
23062310 SymbolReloc :: TlsGd { name } => ( Reloc :: S390xTlsGd64 , name, 0 ) ,
@@ -2319,53 +2323,81 @@ impl Inst {
23192323 let opcode = 0x38 ; // LER
23202324 put ( sink, & enc_rr ( opcode, rd. to_reg ( ) , rn) ) ;
23212325 } else {
2322- let opcode = 0xe756 ; // VLR
2323- put ( sink, & enc_vrr_a ( opcode, rd. to_reg ( ) , rn, 0 , 0 , 0 ) ) ;
2326+ put ( sink, & enc_vrr_a ( OPCODE_VLR , rd. to_reg ( ) , rn, 0 , 0 , 0 ) ) ;
23242327 }
23252328 }
23262329 & Inst :: FpuMove64 { rd, rn } => {
23272330 if is_fpr ( rd. to_reg ( ) ) && is_fpr ( rn) {
2328- let opcode = 0x28 ; // LDR
2329- put ( sink, & enc_rr ( opcode, rd. to_reg ( ) , rn) ) ;
2331+ put ( sink, & enc_rr ( OPCODE_LDR , rd. to_reg ( ) , rn) ) ;
23302332 } else {
2331- let opcode = 0xe756 ; // VLR
2332- put ( sink, & enc_vrr_a ( opcode, rd. to_reg ( ) , rn, 0 , 0 , 0 ) ) ;
2333+ put ( sink, & enc_vrr_a ( OPCODE_VLR , rd. to_reg ( ) , rn, 0 , 0 , 0 ) ) ;
23332334 }
23342335 }
23352336 & Inst :: FpuCMov32 { rd, cond, ri, rm } => {
23362337 debug_assert_eq ! ( rd. to_reg( ) , ri) ;
23372338
23382339 if is_fpr ( rd. to_reg ( ) ) && is_fpr ( rm) {
2339- let opcode = 0xa74 ; // BCR
2340- put ( sink, & enc_ri_c ( opcode, cond. invert ( ) . bits ( ) , 4 + 2 ) ) ;
2340+ put ( sink, & enc_ri_c ( OPCODE_BCR , cond. invert ( ) . bits ( ) , 4 + 2 ) ) ;
23412341 let opcode = 0x38 ; // LER
23422342 put ( sink, & enc_rr ( opcode, rd. to_reg ( ) , rm) ) ;
23432343 } else {
2344- let opcode = 0xa74 ; // BCR
2345- put ( sink, & enc_ri_c ( opcode, cond. invert ( ) . bits ( ) , 4 + 6 ) ) ;
2346- let opcode = 0xe756 ; // VLR
2347- put ( sink, & enc_vrr_a ( opcode, rd. to_reg ( ) , rm, 0 , 0 , 0 ) ) ;
2344+ put ( sink, & enc_ri_c ( OPCODE_BCR , cond. invert ( ) . bits ( ) , 4 + 6 ) ) ;
2345+ put ( sink, & enc_vrr_a ( OPCODE_VLR , rd. to_reg ( ) , rm, 0 , 0 , 0 ) ) ;
23482346 }
23492347 }
23502348 & Inst :: FpuCMov64 { rd, cond, ri, rm } => {
23512349 debug_assert_eq ! ( rd. to_reg( ) , ri) ;
23522350
23532351 if is_fpr ( rd. to_reg ( ) ) && is_fpr ( rm) {
2354- let opcode = 0xa74 ; // BCR
2355- put ( sink, & enc_ri_c ( opcode, cond. invert ( ) . bits ( ) , 4 + 2 ) ) ;
2356- let opcode = 0x28 ; // LDR
2357- put ( sink, & enc_rr ( opcode, rd. to_reg ( ) , rm) ) ;
2352+ put ( sink, & enc_ri_c ( OPCODE_BCR , cond. invert ( ) . bits ( ) , 4 + 2 ) ) ;
2353+ put ( sink, & enc_rr ( OPCODE_LDR , rd. to_reg ( ) , rm) ) ;
2354+ } else {
2355+ put ( sink, & enc_ri_c ( OPCODE_BCR , cond. invert ( ) . bits ( ) , 4 + 6 ) ) ;
2356+ put ( sink, & enc_vrr_a ( OPCODE_VLR , rd. to_reg ( ) , rm, 0 , 0 , 0 ) ) ;
2357+ }
2358+ }
2359+ & Inst :: FpuCMov6464 {
2360+ rd1,
2361+ rd2,
2362+ cond,
2363+ ri1,
2364+ ri2,
2365+ rm1,
2366+ rm2,
2367+ } => {
2368+ debug_assert_eq ! ( rd1. to_reg( ) , ri1) ;
2369+ debug_assert_eq ! ( rd2. to_reg( ) , ri2) ;
2370+
2371+ let is_fpr_1 = is_fpr ( rd1. to_reg ( ) ) && is_fpr ( rm1) ;
2372+ let is_fpr_2 = is_fpr ( rd2. to_reg ( ) ) && is_fpr ( rm2) ;
2373+ let offset = 4 + if is_fpr_1 { 2 } else { 6 } + if is_fpr_2 { 2 } else { 6 } ;
2374+ put ( sink, & enc_ri_c ( OPCODE_BCR , cond. invert ( ) . bits ( ) , offset) ) ;
2375+ if is_fpr_1 {
2376+ put ( sink, & enc_rr ( OPCODE_LDR , rd1. to_reg ( ) , rm1) ) ;
23582377 } else {
2359- let opcode = 0xa74 ; // BCR
2360- put ( sink, & enc_ri_c ( opcode, cond. invert ( ) . bits ( ) , 4 + 6 ) ) ;
2361- let opcode = 0xe756 ; // VLR
2362- put ( sink, & enc_vrr_a ( opcode, rd. to_reg ( ) , rm, 0 , 0 , 0 ) ) ;
2378+ put ( sink, & enc_vrr_a ( OPCODE_VLR , rd1. to_reg ( ) , rm1, 0 , 0 , 0 ) ) ;
23632379 }
2380+ if is_fpr_2 {
2381+ put ( sink, & enc_rr ( OPCODE_LDR , rd2. to_reg ( ) , rm2) ) ;
2382+ } else {
2383+ put ( sink, & enc_vrr_a ( OPCODE_VLR , rd2. to_reg ( ) , rm2, 0 , 0 , 0 ) ) ;
2384+ }
2385+ }
2386+ & Inst :: LoadFpuConst16 { rd, const_data } => {
2387+ let reg = writable_spilltmp_reg ( ) . to_reg ( ) ;
2388+ put ( sink, & enc_ri_b ( OPCODE_BRAS , reg, 6 ) ) ;
2389+ sink. put2 ( const_data. swap_bytes ( ) ) ;
2390+ let inst = Inst :: VecLoadLaneUndef {
2391+ size : 16 ,
2392+ rd,
2393+ mem : MemArg :: reg ( reg, MemFlags :: trusted ( ) ) ,
2394+ lane_imm : 0 ,
2395+ } ;
2396+ inst. emit ( sink, emit_info, state) ;
23642397 }
23652398 & Inst :: LoadFpuConst32 { rd, const_data } => {
2366- let opcode = 0xa75 ; // BRAS
23672399 let reg = writable_spilltmp_reg ( ) . to_reg ( ) ;
2368- put ( sink, & enc_ri_b ( opcode , reg, 8 ) ) ;
2400+ put ( sink, & enc_ri_b ( OPCODE_BRAS , reg, 8 ) ) ;
23692401 sink. put4 ( const_data. swap_bytes ( ) ) ;
23702402 let inst = Inst :: VecLoadLaneUndef {
23712403 size : 32 ,
@@ -2376,9 +2408,8 @@ impl Inst {
23762408 inst. emit ( sink, emit_info, state) ;
23772409 }
23782410 & Inst :: LoadFpuConst64 { rd, const_data } => {
2379- let opcode = 0xa75 ; // BRAS
23802411 let reg = writable_spilltmp_reg ( ) . to_reg ( ) ;
2381- put ( sink, & enc_ri_b ( opcode , reg, 12 ) ) ;
2412+ put ( sink, & enc_ri_b ( OPCODE_BRAS , reg, 12 ) ) ;
23822413 sink. put8 ( const_data. swap_bytes ( ) ) ;
23832414 let inst = Inst :: VecLoadLaneUndef {
23842415 size : 64 ,
@@ -2780,8 +2811,7 @@ impl Inst {
27802811 put ( sink, & enc_vrr_a ( opcode, rm, rn, m3, 0 , 0 ) ) ;
27812812
27822813 // If CC != 0, we'd done, so jump over the next instruction.
2783- let opcode = 0xa74 ; // BCR
2784- put ( sink, & enc_ri_c ( opcode, 7 , 4 + 6 ) ) ;
2814+ put ( sink, & enc_ri_c ( OPCODE_BCR , 7 , 4 + 6 ) ) ;
27852815
27862816 // Otherwise, use VECTOR COMPARE HIGH LOGICAL.
27872817 // Since we already know the high parts are equal, the CC
@@ -2864,25 +2894,21 @@ impl Inst {
28642894 }
28652895
28662896 & Inst :: VecMov { rd, rn } => {
2867- let opcode = 0xe756 ; // VLR
2868- put ( sink, & enc_vrr_a ( opcode, rd. to_reg ( ) , rn, 0 , 0 , 0 ) ) ;
2897+ put ( sink, & enc_vrr_a ( OPCODE_VLR , rd. to_reg ( ) , rn, 0 , 0 , 0 ) ) ;
28692898 }
28702899 & Inst :: VecCMov { rd, cond, ri, rm } => {
28712900 debug_assert_eq ! ( rd. to_reg( ) , ri) ;
28722901
2873- let opcode = 0xa74 ; // BCR
2874- put ( sink, & enc_ri_c ( opcode, cond. invert ( ) . bits ( ) , 4 + 6 ) ) ;
2875- let opcode = 0xe756 ; // VLR
2876- put ( sink, & enc_vrr_a ( opcode, rd. to_reg ( ) , rm, 0 , 0 , 0 ) ) ;
2902+ put ( sink, & enc_ri_c ( OPCODE_BCR , cond. invert ( ) . bits ( ) , 4 + 6 ) ) ;
2903+ put ( sink, & enc_vrr_a ( OPCODE_VLR , rd. to_reg ( ) , rm, 0 , 0 , 0 ) ) ;
28772904 }
28782905 & Inst :: MovToVec128 { rd, rn, rm } => {
28792906 let opcode = 0xe762 ; // VLVGP
28802907 put ( sink, & enc_vrr_f ( opcode, rd. to_reg ( ) , rn, rm) ) ;
28812908 }
28822909 & Inst :: VecLoadConst { rd, const_data } => {
2883- let opcode = 0xa75 ; // BRAS
28842910 let reg = writable_spilltmp_reg ( ) . to_reg ( ) ;
2885- put ( sink, & enc_ri_b ( opcode , reg, 20 ) ) ;
2911+ put ( sink, & enc_ri_b ( OPCODE_BRAS , reg, 20 ) ) ;
28862912 for i in const_data. to_be_bytes ( ) . iter ( ) {
28872913 sink. put1 ( * i) ;
28882914 }
@@ -2897,9 +2923,8 @@ impl Inst {
28972923 rd,
28982924 const_data,
28992925 } => {
2900- let opcode = 0xa75 ; // BRAS
29012926 let reg = writable_spilltmp_reg ( ) . to_reg ( ) ;
2902- put ( sink, & enc_ri_b ( opcode , reg, ( 4 + size / 8 ) as i32 ) ) ;
2927+ put ( sink, & enc_ri_b ( OPCODE_BRAS , reg, ( 4 + size / 8 ) as i32 ) ) ;
29032928 for i in 0 ..size / 8 {
29042929 sink. put1 ( ( const_data >> ( size - 8 - 8 * i) ) as u8 ) ;
29052930 }
0 commit comments