⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m32r.md

📁 linux下的gcc编译器
💻 MD
📖 第 1 页 / 共 5 页
字号:
  int shift;  /* In all cases we will emit two instructions.  However we try to     use 2 byte instructions wherever possible.  We can assume the     constant isn't loadable with any of ldi, ld24, or seth.  */  /* See if we can load a 24 bit unsigned value and invert it.  */  if (UINT24_P (~ val))    {      emit_insn (gen_movsi (operands[0], GEN_INT (~ val)));      emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));      DONE;    }  /* See if we can load a 24 bit unsigned value and shift it into place.     0x01fffffe is just beyond ld24's range.  */  for (shift = 1, tmp = 0x01fffffe;       shift < 8;       ++shift, tmp <<= 1)    {      if ((val & ~tmp) == 0)	{	  emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift)));	  emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift)));	  DONE;	}    }  /* Can't use any two byte insn, fall back to seth/or3.  Use ~0xffff instead     of 0xffff0000, since the later fails on a 64-bit host.  */  operands[2] = GEN_INT ((val) & ~0xffff);  operands[3] = GEN_INT ((val) & 0xffff);}")(define_split  [(set (match_operand:SI 0 "register_operand" "")	(match_operand:SI 1 "seth_add3_operand" "i"))]  "TARGET_ADDR32"  [(set (match_dup 0)	(high:SI (match_dup 1)))   (set (match_dup 0)	(lo_sum:SI (match_dup 0)		   (match_dup 1)))]  "");; Small data area support.;; The address of _SDA_BASE_ is loaded into a register and all objects in;; the small data area are indexed off that.  This is done for each reference;; but cse will clean things up for us.  We let the compiler choose the;; register to use so we needn't allocate (and maybe even fix) a special;; register to use.  Since the load and store insns have a 16 bit offset the;; total size of the data area can be 64K.  However, if the data area lives;; above 16M (24 bits), _SDA_BASE_ will have to be loaded with seth/add3 which;; would then yield 3 instructions to reference an object [though there would;; be no net loss if two or more objects were referenced].  The 3 insns can be;; reduced back to 2 if the size of the small data area were reduced to 32K;; [then seth + ld/st would work for any object in the area].  Doing this;; would require special handling of _SDA_BASE_ (its value would be;; (.sdata + 32K) & 0xffff0000) and reloc computations would be different;; [I think].  What to do about this is deferred until later and for now we;; require .sdata to be in the first 16M.(define_expand "movsi_sda"  [(set (match_dup 2)	(unspec [(const_int 0)] 2))   (set (match_operand:SI 0 "register_operand" "")	(lo_sum:SI (match_dup 2)		   (match_operand:SI 1 "small_data_operand" "")))]  ""  "{  if (reload_in_progress || reload_completed)    operands[2] = operands[0];  else    operands[2] = gen_reg_rtx (SImode);}")(define_insn "*load_sda_base"  [(set (match_operand:SI 0 "register_operand" "=r")	(unspec [(const_int 0)] 2))]  ""  "ld24 %0,#_SDA_BASE_"  [(set_attr "type" "int4")   (set_attr "length" "4")]);; 32 bit address support.(define_expand "movsi_addr32"  [(set (match_dup 2)	; addr32_operand isn't used because it's too restrictive,	; seth_add3_operand is more general and thus safer.	(high:SI (match_operand:SI 1 "seth_add3_operand" "")))   (set (match_operand:SI 0 "register_operand" "")	(lo_sum:SI (match_dup 2) (match_dup 1)))]  ""  "{  if (reload_in_progress || reload_completed)    operands[2] = operands[0];  else    operands[2] = gen_reg_rtx (SImode);}")(define_insn "set_hi_si"  [(set (match_operand:SI 0 "register_operand" "=r")	(high:SI (match_operand 1 "symbolic_operand" "")))]  ""  "seth %0,%#shigh(%1)"  [(set_attr "type" "int4")   (set_attr "length" "4")])(define_insn "lo_sum_si"  [(set (match_operand:SI 0 "register_operand" "=r")	(lo_sum:SI (match_operand:SI 1 "register_operand" "r")		   (match_operand:SI 2 "immediate_operand" "in")))]  ""  "add3 %0,%1,%#%B2"  [(set_attr "type" "int4")   (set_attr "length" "4")])(define_expand "movdi"  [(set (match_operand:DI 0 "general_operand" "")	(match_operand:DI 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (DImode, operands[1]);}")(define_insn "*movdi_insn"  [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,r,m")	(match_operand:DI 1 "move_double_src_operand" "r,nG,F,m,r"))]  "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"  "#"  [(set_attr "type" "multi,multi,multi,load8,store8")   (set_attr "length" "4,4,16,6,6")])(define_split  [(set (match_operand:DI 0 "move_dest_operand" "")	(match_operand:DI 1 "move_double_src_operand" ""))]  "reload_completed"  [(match_dup 2)]  "operands[2] = gen_split_move_double (operands);");; Floating point move insns.(define_expand "movsf"  [(set (match_operand:SF 0 "general_operand" "")	(match_operand:SF 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (SFmode, operands[1]);}")(define_insn "*movsf_insn"  [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,r,r,T,S,m")	(match_operand:SF 1 "move_src_operand" "r,F,U,S,m,r,r,r"))]  "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)"  "@   mv %0,%1   #   ld %0,%1   ld %0,%1   ld %0,%1   st %1,%0   st %1,%0   st %1,%0"  ;; ??? Length of alternative 1 is either 2, 4 or 8.  [(set_attr "type" "int2,multi,load2,load2,load4,store2,store2,store4")   (set_attr "length" "2,8,2,2,4,2,2,4")])(define_split  [(set (match_operand:SF 0 "register_operand" "")	(match_operand:SF 1 "const_double_operand" ""))]  "reload_completed"  [(set (match_dup 2) (match_dup 3))]  "{  operands[2] = operand_subword (operands[0], 0, 0, SFmode);  operands[3] = operand_subword (operands[1], 0, 0, SFmode);}")(define_expand "movdf"  [(set (match_operand:DF 0 "general_operand" "")	(match_operand:DF 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (DFmode, operands[1]);}")(define_insn "*movdf_insn"  [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")	(match_operand:DF 1 "move_double_src_operand" "r,F,m,r"))]  "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"  "#"  [(set_attr "type" "multi,multi,load8,store8")   (set_attr "length" "4,16,6,6")])(define_split  [(set (match_operand:DF 0 "move_dest_operand" "")	(match_operand:DF 1 "move_double_src_operand" ""))]  "reload_completed"  [(match_dup 2)]  "operands[2] = gen_split_move_double (operands);");; Zero extension instructions.(define_insn "zero_extendqihi2"  [(set (match_operand:HI 0 "register_operand" "=r,r,r")	(zero_extend:HI (match_operand:QI 1 "extend_operand" "r,T,m")))]  ""  "@   and3 %0,%1,%#255   ldub %0,%1   ldub %0,%1"  [(set_attr "type" "int4,load2,load4")   (set_attr "length" "4,2,4")])(define_insn "zero_extendqisi2"  [(set (match_operand:SI 0 "register_operand" "=r,r,r")	(zero_extend:SI (match_operand:QI 1 "extend_operand" "r,T,m")))]  ""  "@   and3 %0,%1,%#255   ldub %0,%1   ldub %0,%1"  [(set_attr "type" "int4,load2,load4")   (set_attr "length" "4,2,4")])(define_insn "zero_extendhisi2"  [(set (match_operand:SI 0 "register_operand" "=r,r,r")	(zero_extend:SI (match_operand:HI 1 "extend_operand" "r,T,m")))]  ""  "@   and3 %0,%1,%#65535   lduh %0,%1   lduh %0,%1"  [(set_attr "type" "int4,load2,load4")   (set_attr "length" "4,2,4")]);; Signed conversions from a smaller integer to a larger integer(define_insn "extendqihi2"  [(set (match_operand:HI 0 "register_operand" "=r,r,r")	(sign_extend:HI (match_operand:QI 1 "extend_operand" "0,T,m")))]  ""  "@    #    ldb %0,%1    ldb %0,%1"  [(set_attr "type" "multi,load2,load4")   (set_attr "length" "2,2,4")])(define_split  [(set (match_operand:HI 0 "register_operand" "")	(sign_extend:HI (match_operand:QI 1 "register_operand" "")))]  "reload_completed"  [(match_dup 2)   (match_dup 3)]  "{  rtx op0   = gen_lowpart (SImode, operands[0]);  rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);  operands[2] = gen_ashlsi3 (op0, op0, shift);  operands[3] = gen_ashrsi3 (op0, op0, shift);}")(define_insn "extendqisi2"  [(set (match_operand:SI 0 "register_operand" "=r,r,r")	(sign_extend:SI (match_operand:QI 1 "extend_operand" "0,T,m")))]  ""  "@    #    ldb %0,%1    ldb %0,%1"  [(set_attr "type" "multi,load2,load4")   (set_attr "length" "4,2,4")])(define_split  [(set (match_operand:SI 0 "register_operand" "")	(sign_extend:SI (match_operand:QI 1 "register_operand" "")))]  "reload_completed"  [(match_dup 2)   (match_dup 3)]  "{  rtx op0   = gen_lowpart (SImode, operands[0]);  rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);  operands[2] = gen_ashlsi3 (op0, op0, shift);  operands[3] = gen_ashrsi3 (op0, op0, shift);}")(define_insn "extendhisi2"  [(set (match_operand:SI 0 "register_operand" "=r,r,r")	(sign_extend:SI (match_operand:HI 1 "extend_operand" "0,T,m")))]  ""  "@    #    ldh %0,%1    ldh %0,%1"  [(set_attr "type" "multi,load2,load4")   (set_attr "length" "4,2,4")])(define_split  [(set (match_operand:SI 0 "register_operand" "")	(sign_extend:SI (match_operand:HI 1 "register_operand" "")))]  "reload_completed"  [(match_dup 2)   (match_dup 3)]  "{  rtx op0   = gen_lowpart (SImode, operands[0]);  rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);  operands[2] = gen_ashlsi3 (op0, op0, shift);  operands[3] = gen_ashrsi3 (op0, op0, shift);}");; Arithmetic instructions.; ??? Adding an alternative to split add3 of small constants into two; insns yields better instruction packing but slower code.  Adds of small; values is done a lot.(define_insn "addsi3"  [(set (match_operand:SI 0 "register_operand" "=r,r,r")	(plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")		 (match_operand:SI 2 "nonmemory_operand" "r,I,J")))]  ""  "@   add %0,%2   addi %0,%#%2   add3 %0,%1,%#%2"  [(set_attr "type" "int2,int2,int4")   (set_attr "length" "2,2,4")]);(define_split;  [(set (match_operand:SI 0 "register_operand" "");	(plus:SI (match_operand:SI 1 "register_operand" "");		 (match_operand:SI 2 "int8_operand" "")))];  "reload_completed;   && REGNO (operands[0]) != REGNO (operands[1]);   && INT8_P (INTVAL (operands[2]));   && INTVAL (operands[2]) != 0";  [(set (match_dup 0) (match_dup 1));   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))];  "")(define_insn "adddi3"  [(set (match_operand:DI 0 "register_operand" "=r")	(plus:DI (match_operand:DI 1 "register_operand" "%0")		 (match_operand:DI 2 "register_operand" "r")))   (clobber (reg:SI 17))]  ""  "#"  [(set_attr "type" "multi")   (set_attr "length" "6")]);; ??? The cmp clears the condition bit.  Can we speed up somehow?(define_split  [(set (match_operand:DI 0 "register_operand" "")	(plus:DI (match_operand:DI 1 "register_operand" "")		 (match_operand:DI 2 "register_operand" "")))   (clobber (match_operand 3 "" ""))]  "reload_completed"  [(parallel [(set (match_dup 3)		   (const_int 0))	      (use (match_dup 4))])   (parallel [(set (match_dup 4)		   (plus:SI (match_dup 4)			    (plus:SI (match_dup 5)				     (match_dup 3))))	      (set (match_dup 3)		   (unspec [(const_int 0)] 3))])   (parallel [(set (match_dup 6)		   (plus:SI (match_dup 6)			    (plus:SI (match_dup 7)				     (match_dup 3))))	      (set (match_dup 3)		   (unspec [(const_int 0)] 3))])]  "{  operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);  operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);  operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);  operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);}")(define_insn "*clear_c"  [(set (reg:SI 17)	(const_int 0))   (use (match_operand:SI 0 "register_operand" "r"))]  ""  "cmp %0,%0"  [(set_attr "type" "int2")   (set_attr "length" "2")])(define_insn "*add_carry"  [(set (match_operand:SI 0 "register_operand" "=r")	(plus:SI (match_operand:SI 1 "register_operand" "%0")		 (plus:SI (match_operand:SI 2 "register_operand" "r")			  (reg:SI 17))))   (set (reg:SI 17)	(unspec [(const_int 0)] 3))]  ""  "addx %0,%2"  [(set_attr "type" "int2")   (set_attr "length" "2")])(define_insn "subsi3"  [(set (match_operand:SI 0 "register_operand" "=r")	(minus:SI (match_operand:SI 1 "register_operand" "0")		  (match_operand:SI 2 "register_operand" "r")))]  ""  "sub %0,%2"  [(set_attr "type" "int2")   (set_attr "length" "2")])(define_insn "subdi3"  [(set (match_operand:DI 0 "register_operand" "=r")	(minus:DI (match_operand:DI 1 "register_operand" "0")		  (match_operand:DI 2 "register_operand" "r")))   (clobber (reg:SI 17))]  ""  "#"  [(set_attr "type" "multi")   (set_attr "length" "6")]);; ??? The cmp clears the condition bit.  Can we speed up somehow?(define_split  [(set (match_operand:DI 0 "register_operand" "")	(minus:DI (match_operand:DI 1 "register_operand" "")		  (match_operand:DI 2 "register_operand" "")))   (clobber (match_operand 3 "" ""))]  "reload_completed"  [(parallel [(set (match_dup 3)		   (const_int 0))	      (use (match_dup 4))])   (parallel [(set (match_dup 4)		   (minus:SI (match_dup 4)			     (minus:SI (match_dup 5)				       (match_dup 3))))	      (set (match_dup 3)		   (unspec [(const_int 0)] 3))])   (parallel [(set (match_dup 6)		   (minus:SI (match_dup 6)			     (minus:SI (match_dup 7)				       (match_dup 3))))	      (set (match_dup 3)		   (unspec [(const_int 0)] 3))])]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -