URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [or32/] [or32.md] - Rev 414
Compare with Previous | Blame | View Log
;; Machine description for GNU compiler, OpenRISC 1000 family, OR32 ISA;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,;; 2009, 2010 Free Software Foundation, Inc.;; Copyright (C) 2010 Embecosm Limited;; Contributed by Damjan Lampret <damjanl@bsemi.com> in 1999.;; Major optimizations by Matjaz Breskvar <matjazb@bsemi.com> in 2005.;; Floating point additions by Jungsook Yang <jungsook.yang@uci.edu>;; Julius Baxter <julius@orsoc.se> in 2010;; Updated for GCC 4.5 by Jeremy Bennett <jeremy.bennett@embecosm.com>;; and Joern Rennecke <joern.rennecke@embecosm.com> in 2010;; This file is part of GNU CC.;; This program is free software; you can redistribute it and/or modify it;; under the terms of the GNU General Public License as published by the Free;; Software Foundation; either version 3 of the License, or (at your option);; any later version.;;;; This program is distributed in the hope that it will be useful, but WITHOUT;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for;; more details.;;;; You should have received a copy of the GNU General Public License along;; with this program. If not, see <http://www.gnu.org/licenses/>. */(define_constants [(SP_REG 1)(FP_REG 2) ; hard frame pointer(CC_REG 34);; unspec values(UNSPEC_FRAME 0);; unspec_volatile values(UNSPECV_SIBCALL_EPILOGUE 0)])(include "predicates.md")(include "constraints.md")(define_attr "type""unknown,load,store,move,extend,logic,add,mul,shift,compare,branch,jump,fp,jump_restore"(const_string "unknown"));; Number of machine instructions required to implement an insn.(define_attr "length" "" (const_int 1));; Single delay slot after branch or jump instructions, wich may contain any;; instruction but another branch or jump.(define_delay (eq_attr "type" "branch,jump")[(and (eq_attr "type" "!branch,jump")(eq_attr "length" "1")) (nil) (nil)]);; ALU is modelled as a single functional unit, which is reserved for varying;; numbers of slots.;;;; I think this is all incorrect for the OR1K. The latency says when the;; result will be ready, not how long the pipeline takes to execute.(define_cpu_unit "or32_alu")(define_insn_reservation "bit_unit" 3 (eq_attr "type" "shift") "or32_alu")(define_insn_reservation "lsu_load" 3 (eq_attr "type" "load") "or32_alu*3")(define_insn_reservation "lsu_store" 2 (eq_attr "type" "store") "or32_alu")(define_insn_reservation "alu_unit" 2(eq_attr "type" "add,logic,extend,move,compare")"or32_alu")(define_insn_reservation "mul_unit" 16 (eq_attr "type" "mul") "or32_alu*16");; Called after register allocation to add any instructions needed for the;; prologue. Using a prologue insn is favored compared to putting all of the;; instructions in output_function_prologue(), since it allows the scheduler;; to intermix instructions with the saves of the caller saved registers. In;; some cases, it might be necessary to emit a barrier instruction as the last;; insn to prevent such scheduling.(define_expand "prologue"[(use (const_int 1))]"TARGET_SCHED_LOGUE"{or32_expand_prologue ();DONE;});; Called after register allocation to add any instructions needed for the;; epilogue. Using an epilogue insn is favored compared to putting all of the;; instructions in output_function_epilogue(), since it allows the scheduler;; to intermix instructions with the restores of the caller saved registers.;; In some cases, it might be necessary to emit a barrier instruction as the;; first insn to prevent such scheduling.(define_expand "epilogue"[(use (const_int 2))]"TARGET_SCHED_LOGUE"{or32_expand_epilogue (NULL_RTX);DONE;})(define_insn_and_split "sibcall_epilogue"[(unspec_volatile [(const_int 2)] UNSPECV_SIBCALL_EPILOGUE)]"TARGET_SCHED_LOGUE""#"""[(pc)]{or32_expand_epilogue (curr_insn);DONE;})(define_insn "frame_dealloc_fp"[(set (reg:SI SP_REG) (reg:SI FP_REG))(clobber (mem:QI (plus:SI (reg:SI FP_REG)(unspec:SI [(const_int FP_REG)] UNSPEC_FRAME))))]"""l.ori\tr1,r2,0\t# deallocate frame"[(set_attr "type" "logic")(set_attr "length" "1")])(define_insn "frame_dealloc_sp"[(set (reg:SI SP_REG)(plus:SI (reg:SI SP_REG)(match_operand:SI 0 "nonmemory_operand" "r,I")))(clobber (mem:QI (plus:SI (reg:SI SP_REG)(unspec:SI [(const_int SP_REG)] UNSPEC_FRAME))))]"""@l.add\tr1,r1,%0l.addi\tr1,r1,%0"[(set_attr "type" "add")(set_attr "length" "1")])(define_insn "return_internal"[(return)(use (match_operand 0 "pmode_register_operand" ""))]"TARGET_SCHED_LOGUE""l.jr \t%0%("[(set_attr "type" "jump")(set_attr "length" "1")]);;;; Sibcalls;;(define_expand "sibcall"[(parallel [(call (match_operand 0 "" "")(match_operand 1 "" ""))(use (match_operand 2 "" "")) ;; next_arg_reg(use (match_operand 3 "" ""))])] ;; struct_value_size_rtx"""{or32_expand_sibcall (0, XEXP (operands[0], 0), operands[1]);DONE;}")(define_expand "sibcall_value"[(set (match_operand 0 "" "")(call (match_operand:SI 1 "" "")(match_operand 2 "" "")))]"""{or32_expand_sibcall (operands[0], XEXP (operands[1], 0), operands[2]);DONE;}")(define_insn "sibcall_internal"[(call (mem:SI (match_operand:SI 0 "sibcall_insn_operand" "s,Rsc,r"))(match_operand 1 "" ""))(use (reg:SI 9))]"""@l.j\t%S0%(\t# sibcall sl.jr\t%0%(\t# sibcall Rscl.jr\t%0\t\t# sibcall r%J0"[(set_attr "type" "jump,jump,jump_restore")]);;;; movQI;;(define_expand "movqi"[(set (match_operand:QI 0 "general_operand" "")(match_operand:QI 1 "general_operand" ""))]"""if (can_create_pseudo_p()){if (GET_CODE (operands[1]) == CONST_INT){rtx reg = gen_reg_rtx (SImode);emit_insn (gen_movsi (reg, operands[1]));operands[1] = gen_lowpart (QImode, reg);}if (GET_CODE (operands[1]) == MEM && optimize > 0){rtx reg = gen_reg_rtx (SImode);emit_insn (gen_rtx_SET (SImode, reg,gen_rtx_ZERO_EXTEND (SImode,operands[1])));operands[1] = gen_lowpart (QImode, reg);}if (GET_CODE (operands[0]) != REG)operands[1] = force_reg (QImode, operands[1]);}")(define_insn "*movqi_internal"[(set (match_operand:QI 0 "nonimmediate_operand" "=m,r,r,r,r")(match_operand:QI 1 "general_operand" "r,r,I,K,m"))]"""@l.sb \t%0,%1\t # movqil.ori \t%0,%1,0\t # movqi: move reg to regl.addi \t%0,r0,%1\t # movqi: move immediatel.ori \t%0,r0,%1\t # movqi: move immediatel.lbz \t%0,%1\t # movqi"[(set_attr "type" "store,add,add,logic,load")]);;;; movHI;;(define_expand "movhi"[(set (match_operand:HI 0 "general_operand" "")(match_operand:HI 1 "general_operand" ""))]"""if (can_create_pseudo_p()){if (GET_CODE (operands[1]) == CONST_INT){rtx reg = gen_reg_rtx (SImode);emit_insn (gen_movsi (reg, operands[1]));operands[1] = gen_lowpart (HImode, reg);}if (GET_CODE (operands[1]) == MEM && optimize > 0){rtx reg = gen_reg_rtx (SImode);emit_insn (gen_rtx_SET (SImode, reg,gen_rtx_ZERO_EXTEND (SImode,operands[1])));operands[1] = gen_lowpart (HImode, reg);}if (GET_CODE (operands[0]) != REG)operands[1] = force_reg (HImode, operands[1]);}")(define_insn "*movhi_internal"[(set (match_operand:HI 0 "nonimmediate_operand" "=m,r,r,r,r")(match_operand:HI 1 "general_operand" "r,r,I,K,m"))]"""@l.sh \t%0,%1\t # movhil.ori \t%0,%1,0\t # movhi: move reg to regl.addi \t%0,r0,%1\t # movhi: move immediatel.ori \t%0,r0,%1\t # movhi: move immediatel.lhz \t%0,%1\t # movhi"[(set_attr "type" "store,add,add,logic,load")])(define_expand "movsi"[(set (match_operand:SI 0 "general_operand" "")(match_operand:SI 1 "general_operand" ""))]""{/* Working with CONST_INTs is easier, so converta double if needed. */if (GET_CODE (operands[1]) == CONST_DOUBLE) {operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));}/* Handle sets of MEM first. */if (GET_CODE (operands[0]) == MEM){if (register_operand(operands[1], SImode)|| (operands[1] == const0_rtx))goto movsi_is_ok;if (! reload_in_progress){operands[0] = validize_mem (operands[0]);operands[1] = force_reg (SImode, operands[1]);}}/* This makes sure we will not get rematched due to splittage. */if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode));else if (CONSTANT_P (operands[1])&& GET_CODE (operands[1]) != HIGH&& GET_CODE (operands[1]) != LO_SUM){or32_emit_set_const32 (operands[0], operands[1]);DONE;}movsi_is_ok:;});;;; movSI;;(define_insn "*movsi_insn"[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")(match_operand:SI 1 "input_operand" "I,K,M,r,m,r"))]"(register_operand (operands[0], SImode)|| register_operand (operands[1], SImode)|| (operands[1] == const0_rtx))""@l.addi \t%0,r0,%1\t # move immediate Il.ori \t%0,r0,%1\t # move immediate Kl.movhi \t%0,hi(%1)\t # move immediate Ml.ori \t%0,%1,0\t # move reg to regl.lwz \t%0,%1\t # SI loadl.sw \t%0,%1\t # SI store"[(set_attr "type" "add,load,store,add,logic,move")(set_attr "length" "1,1,1,1,1,1")])(define_insn "movsi_lo_sum"[(set (match_operand:SI 0 "register_operand" "=r")(lo_sum:SI (match_operand:SI 1 "register_operand" "r")(match_operand:SI 2 "immediate_operand" "i")))]"""l.ori \t%0,%1,lo(%2)"[(set_attr "type" "logic")(set_attr "length" "1")])(define_insn "movsi_high"[(set (match_operand:SI 0 "register_operand" "=r")(high:SI (match_operand:SI 1 "immediate_operand" "i")))]"""l.movhi \t%0,hi(%1)"[(set_attr "type" "move")(set_attr "length" "1")])(define_insn_and_split "movsi_insn_big"[(set (match_operand:SI 0 "register_operand" "=r")(match_operand:SI 1 "immediate_operand" "i"))]"GET_CODE (operands[1]) != CONST_INT""l.movhi \t%0,hi(%1)\;l.ori \t%0,%0,lo(%1)";; the switch of or32 bfd to Rela allows us to schedule insns separately."&& reload_completed&& GET_CODE (operands[1]) != HIGH && GET_CODE (operands[1]) != LO_SUM"[(pc)]{emit_insn (gen_movsi_high (operands[0], operands[1]));emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1]));DONE;}[(set_attr "type" "move")(set_attr "length" "2")]);;;; Conditional Branches & Moves;;(define_expand "addsicc"[(match_operand:SI 0 "register_operand" "")(match_operand 1 "comparison_operator" "")(match_operand:SI 2 "register_operand" "")(match_operand:SI 3 "register_operand" "")]"""FAIL;")(define_expand "addhicc"[(match_operand:HI 0 "register_operand" "")(match_operand 1 "comparison_operator" "")(match_operand:HI 2 "register_operand" "")(match_operand:HI 3 "register_operand" "")]"""FAIL;")(define_expand "addqicc"[(match_operand:QI 0 "register_operand" "")(match_operand 1 "comparison_operator" "")(match_operand:QI 2 "register_operand" "")(match_operand:QI 3 "register_operand" "")]"""FAIL;");;;; conditional moves;;(define_expand "movsicc"[(set (match_operand:SI 0 "register_operand" "")(if_then_else:SI (match_operand 1 "comparison_operator" "")(match_operand:SI 2 "register_operand" "")(match_operand:SI 3 "register_operand" "")))]"TARGET_MASK_CMOV""{if (or32_emit_cmove (operands[0], operands[1], operands[2], operands[3]))DONE;}")(define_expand "movhicc"[(set (match_operand:HI 0 "register_operand" "")(if_then_else:SI (match_operand 1 "comparison_operator" "")(match_operand:HI 2 "register_operand" "")(match_operand:HI 3 "register_operand" "")))]"""{FAIL;}")(define_expand "movqicc"[(set (match_operand:QI 0 "register_operand" "")(if_then_else:SI (match_operand 1 "comparison_operator" "")(match_operand:QI 2 "register_operand" "")(match_operand:QI 3 "register_operand" "")))]"""{FAIL;}");; We use the BASE_REGS for the cmov input operands because, if rA is;; 0, the value of 0 is placed in rD upon truth. Similarly for rB;; because we may switch the operands and rB may end up being rA.(define_insn "cmov"[(set (match_operand:SI 0 "register_operand" "=r")(if_then_else:SI(match_operator 1 "comparison_operator"[(match_operand 4 "cc_reg_operand" "")(const_int 0)])(match_operand:SI 2 "register_operand" "r")(match_operand:SI 3 "register_operand" "r")))]"TARGET_MASK_CMOV""*return or32_output_cmov(operands);");;;; ....................;;;; COMPARISONS;;;; ....................;; Flow here is rather complex:;;;; 1) The cmp{si,di,sf,df} routine is called. It deposits the;; arguments into the branch_cmp array, and the type into;; branch_type. No RTL is generated.;;;; 2) The appropriate branch define_expand is called, which then;; creates the appropriate RTL for the comparison and branch.;; Different CC modes are used, based on what type of branch is;; done, so that we can constrain things appropriately. There;; are assumptions in the rest of GCC that break if we fold the;; operands into the branches for integer operations, and use cc0;; for floating point, so we use the fp status register instead.;; If needed, an appropriate temporary is created to hold the;; of the integer compare.;; Compare insns are next. Note that the RS/6000 has two types of compares,;; signed & unsigned, and one type of branch.;;;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc;; insns, and branches. We store the operands of compares until we see;; how it is used.;; JPB 31-Aug-10: cmpxx appears to be obsolete in GCC 4.5. Needs more;; investigation.;;(define_expand "cmpsi";; [(set (reg:CC CC_REG);; (compare:CC (match_operand:SI 0 "register_operand" "");; (match_operand:SI 1 "nonmemory_operand" "")))];; "";; {;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM);; operands[0] = force_reg (SImode, operands[0]);;; or32_compare_op0 = operands[0];;; or32_compare_op1 = operands[1];;; DONE;;; });; (define_expand "cmpsf";; [(set (reg:CC CC_REG);; (compare:CC (match_operand:SF 0 "register_operand" "");; (match_operand:SF 1 "register_operand" "")))];; "TARGET_HARD_FLOAT";; {;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM);; operands[0] = force_reg (SFmode, operands[0]);;; or32_compare_op0 = operands[0];;; or32_compare_op1 = operands[1];;; DONE;;; })(define_expand "cbranchsi4"[(match_operator 0 "comparison_operator"[(match_operand:SI 1 "register_operand")(match_operand:SI 2 "nonmemory_operand")])(match_operand 3 "")]""{or32_expand_conditional_branch (operands, SImode);DONE;})(define_expand "cbranchsf4"[(match_operator 0 "comparison_operator"[(match_operand:SI 1 "register_operand")(match_operand:SI 2 "register_operand")])(match_operand 3 "")]"TARGET_HARD_FLOAT"{or32_expand_conditional_branch (operands, SFmode);DONE;});;;; Setting a CCxx registers from comparision;;;; Here are the actual compare insns.(define_insn "*cmpsi_eq"[(set (reg:CCEQ CC_REG)(compare:CCEQ (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sfeqi\t%0,%1l.sfeq \t%0,%1")(define_insn "*cmpsi_ne"[(set (reg:CCNE CC_REG)(compare:CCNE (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sfnei\t%0,%1l.sfne \t%0,%1")(define_insn "*cmpsi_gt"[(set (reg:CCGT CC_REG)(compare:CCGT (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sfgtsi\t%0,%1l.sfgts \t%0,%1")(define_insn "*cmpsi_gtu"[(set (reg:CCGTU CC_REG)(compare:CCGTU (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sfgtui\t%0,%1l.sfgtu \t%0,%1")(define_insn "*cmpsi_lt"[(set (reg:CCLT CC_REG)(compare:CCLT (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sfltsi\t%0,%1l.sflts \t%0,%1")(define_insn "*cmpsi_ltu"[(set (reg:CCLTU CC_REG)(compare:CCLTU (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sfltui\t%0,%1l.sfltu \t%0,%1")(define_insn "*cmpsi_ge"[(set (reg:CCGE CC_REG)(compare:CCGE (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sfgesi\t%0,%1l.sfges \t%0,%1")(define_insn "*cmpsi_geu"[(set (reg:CCGEU CC_REG)(compare:CCGEU (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sfgeui\t%0,%1l.sfgeu \t%0,%1")(define_insn "*cmpsi_le"[(set (reg:CCLE CC_REG)(compare:CCLE (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sflesi\t%0,%1l.sfles \t%0,%1")(define_insn "*cmpsi_leu"[(set (reg:CCLEU CC_REG)(compare:CCLEU (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "nonmemory_operand" "I,r")))]"""@l.sfleui\t%0,%1l.sfleu \t%0,%1");; Single precision floating point evaluation instructions(define_insn "*cmpsf_eq"[(set (reg:CCEQ CC_REG)(compare:CCEQ (match_operand:SF 0 "register_operand" "r,r")(match_operand:SF 1 "register_operand" "r,r")))]"TARGET_HARD_FLOAT""lf.sfeq.s\t%0,%1")(define_insn "*cmpsf_ne"[(set (reg:CCNE CC_REG)(compare:CCNE (match_operand:SF 0 "register_operand" "r,r")(match_operand:SF 1 "register_operand" "r,r")))]"TARGET_HARD_FLOAT""lf.sfne.s\t%0,%1")(define_insn "*cmpsf_gt"[(set (reg:CCGT CC_REG)(compare:CCGT (match_operand:SF 0 "register_operand" "r,r")(match_operand:SF 1 "register_operand" "r,r")))]"TARGET_HARD_FLOAT""lf.sfgt.s\t%0,%1")(define_insn "*cmpsf_ge"[(set (reg:CCGE CC_REG)(compare:CCGE (match_operand:SF 0 "register_operand" "r,r")(match_operand:SF 1 "register_operand" "r,r")))]"TARGET_HARD_FLOAT""lf.sfge.s\t%0,%1")(define_insn "*cmpsf_lt"[(set (reg:CCLT CC_REG)(compare:CCLT (match_operand:SF 0 "register_operand" "r,r")(match_operand:SF 1 "register_operand" "r,r")))]"TARGET_HARD_FLOAT""lf.sflt.s\t%0,%1")(define_insn "*cmpsf_le"[(set (reg:CCLE CC_REG)(compare:CCLE (match_operand:SF 0 "register_operand" "r,r")(match_operand:SF 1 "register_operand" "r,r")))]"TARGET_HARD_FLOAT""lf.sfle.s\t%0,%1")(define_insn "*bf"[(set (pc)(if_then_else (match_operator 1 "comparison_operator"[(match_operand 2"cc_reg_operand" "")(const_int 0)])(label_ref (match_operand 0 "" ""))(pc)))]"""*return or32_output_bf(operands);"[(set_attr "type" "branch")(set_attr "length" "1")]);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(define_insn "movdi"[(set (match_operand:DI 0 "nonimmediate_operand" "=r, r, m, r")(match_operand:DI 1 "general_operand" " r, m, r, i"))]"""*return or32_output_move_double (operands);"[(set_attr "length" "2,2,2,3")]);; Moving double and single precision floating point values(define_insn "movdf"[(set (match_operand:DF 0 "nonimmediate_operand" "=r, r, m, r")(match_operand:DF 1 "general_operand" " r, m, r, i"))]"""*return or32_output_move_double (operands);"[(set_attr "length" "2,2,2,3")])(define_insn "movsf"[(set (match_operand:SF 0 "general_operand" "=r,r,m")(match_operand:SF 1 "general_operand" "r,m,r"))]"""@l.ori \t%0,%1,0\t # movsfl.lwz \t%0,%1\t # movsfl.sw \t%0,%1\t # movsf"[(set_attr "type" "move,load,store")(set_attr "length" "1,1,1")]);;;; extendqisi2;;(define_expand "extendqisi2"[(use (match_operand:SI 0 "register_operand" ""))(use (match_operand:QI 1 "nonimmediate_operand" ""))]"""{if (TARGET_MASK_SEXT)emit_insn (gen_extendqisi2_sext(operands[0], operands[1]));else {if ( GET_CODE(operands[1]) == MEM ) {emit_insn (gen_extendqisi2_no_sext_mem(operands[0], operands[1]));}else {emit_insn (gen_extendqisi2_no_sext_reg(operands[0], operands[1]));}}DONE;}")(define_insn "extendqisi2_sext"[(set (match_operand:SI 0 "register_operand" "=r,r")(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]"TARGET_MASK_SEXT""@l.extbs \t%0,%1\t # extendqisi2_has_signed_extendl.lbs \t%0,%1\t # extendqisi2_has_signed_extend"[(set_attr "length" "1,1")(set_attr "type" "extend,load")])(define_insn "extendqisi2_no_sext_mem"[(set (match_operand:SI 0 "register_operand" "=r")(sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]"!TARGET_MASK_SEXT""l.lbs \t%0,%1\t # extendqisi2_no_sext_mem"[(set_attr "length" "1")(set_attr "type" "load")])(define_expand "extendqisi2_no_sext_reg"[(set (match_dup 2)(ashift:SI (match_operand:QI 1 "register_operand" "")(const_int 24)))(set (match_operand:SI 0 "register_operand" "")(ashiftrt:SI (match_dup 2)(const_int 24)))]"!TARGET_MASK_SEXT""{operands[1] = gen_lowpart (SImode, operands[1]);operands[2] = gen_reg_rtx (SImode); }");;;; extendhisi2;;(define_expand "extendhisi2"[(use (match_operand:SI 0 "register_operand" ""))(use (match_operand:HI 1 "nonimmediate_operand" ""))]"""{if (TARGET_MASK_SEXT)emit_insn (gen_extendhisi2_sext(operands[0], operands[1]));else {if ( GET_CODE(operands[1]) == MEM ) {emit_insn (gen_extendhisi2_no_sext_mem(operands[0], operands[1]));}else {emit_insn (gen_extendhisi2_no_sext_reg(operands[0], operands[1]));}}DONE;}")(define_insn "extendhisi2_sext"[(set (match_operand:SI 0 "register_operand" "=r,r")(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]"TARGET_MASK_SEXT""@l.exths \t%0,%1\t # extendhisi2_has_signed_extendl.lhs \t%0,%1\t # extendhisi2_has_signed_extend"[(set_attr "length" "1,1")(set_attr "type" "extend,load")])(define_insn "extendhisi2_no_sext_mem"[(set (match_operand:SI 0 "register_operand" "=r")(sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]"!TARGET_MASK_SEXT""l.lhs \t%0,%1\t # extendhisi2_no_sext_mem"[(set_attr "length" "1")(set_attr "type" "load")])(define_expand "extendhisi2_no_sext_reg"[(set (match_dup 2)(ashift:SI (match_operand:HI 1 "register_operand" "")(const_int 16)))(set (match_operand:SI 0 "register_operand" "")(ashiftrt:SI (match_dup 2)(const_int 16)))]"!TARGET_MASK_SEXT""{operands[1] = gen_lowpart (SImode, operands[1]);operands[2] = gen_reg_rtx (SImode); }");;;; zero_extend<m><n>2;;(define_insn "zero_extendqisi2"[(set (match_operand:SI 0 "register_operand" "=r,r")(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]"""@l.andi \t%0,%1,0xff\t # zero_extendqisi2l.lbz \t%0,%1\t # zero_extendqisi2"[(set_attr "type" "logic,load")(set_attr "length" "1,1")])(define_insn "zero_extendhisi2"[(set (match_operand:SI 0 "register_operand" "=r,r")(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]"""@l.andi \t%0,%1,0xffff\t # zero_extendqisi2l.lhz \t%0,%1\t # zero_extendqisi2"[(set_attr "type" "logic,load")(set_attr "length" "1,1")]);;;; Shift/rotate operations;;(define_insn "ashlsi3"[(set (match_operand:SI 0 "register_operand" "=r,r")(ashift:SI (match_operand:SI 1 "register_operand" "r,r")(match_operand:SI 2 "nonmemory_operand" "r,L")))]"""@l.sll \t%0,%1,%2l.slli \t%0,%1,%2"[(set_attr "type" "shift,shift")(set_attr "length" "1,1")])(define_insn "ashrsi3"[(set (match_operand:SI 0 "register_operand" "=r,r")(ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")(match_operand:SI 2 "nonmemory_operand" "r,L")))]"""@l.sra \t%0,%1,%2l.srai \t%0,%1,%2"[(set_attr "type" "shift,shift")(set_attr "length" "1,1")])(define_insn "lshrsi3"[(set (match_operand:SI 0 "register_operand" "=r,r")(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")(match_operand:SI 2 "nonmemory_operand" "r,L")))]"""@l.srl \t%0,%1,%2l.srli \t%0,%1,%2"[(set_attr "type" "shift,shift")(set_attr "length" "1,1")])(define_insn "rotrsi3"[(set (match_operand:SI 0 "register_operand" "=r,r")(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")(match_operand:SI 2 "nonmemory_operand" "r,L")))]"TARGET_MASK_ROR""@l.ror \t%0,%1,%2l.rori \t%0,%1,%2"[(set_attr "type" "shift,shift")(set_attr "length" "1,1")]);;;; Logical bitwise operations;;(define_insn "andsi3"[(set (match_operand:SI 0 "register_operand" "=r,r")(and:SI (match_operand:SI 1 "register_operand" "%r,r")(match_operand:SI 2 "nonmemory_operand" "r,K")))]"""@l.and \t%0,%1,%2l.andi \t%0,%1,%2"[(set_attr "type" "logic,logic")(set_attr "length" "1,1")])(define_insn "iorsi3"[(set (match_operand:SI 0 "register_operand" "=r,r")(ior:SI (match_operand:SI 1 "register_operand" "%r,r")(match_operand:SI 2 "nonmemory_operand" "r,K")))]"""@l.or \t%0,%1,%2l.ori \t%0,%1,%2"[(set_attr "type" "logic,logic")(set_attr "length" "1,1")])(define_insn "xorsi3"[(set (match_operand:SI 0 "register_operand" "=r,r")(xor:SI (match_operand:SI 1 "register_operand" "%r,r")(match_operand:SI 2 "nonmemory_operand" "r,I")))]"""@l.xor \t%0,%1,%2l.xori \t%0,%1,%2"[(set_attr "type" "logic,logic")(set_attr "length" "1,1")])(define_insn "one_cmplqi2"[(set (match_operand:QI 0 "register_operand" "=r")(not:QI (match_operand:QI 1 "register_operand" "r")))]"""l.xori \t%0,%1,0x00ff"[(set_attr "type" "logic")(set_attr "length" "1")])(define_insn "one_cmplsi2"[(set (match_operand:SI 0 "register_operand" "=r")(not:SI (match_operand:SI 1 "register_operand" "r")))]"""l.xori \t%0,%1,0xffff"[(set_attr "type" "logic")(set_attr "length" "1")]);;;; Arithmetic operations;;(define_insn "negsi2"[(set (match_operand:SI 0 "register_operand" "=r")(neg:SI (match_operand:SI 1 "register_operand" "r")))]"""l.sub \t%0,r0,%1"[(set_attr "type" "add")(set_attr "length" "1")])(define_insn "addsi3"[(set (match_operand:SI 0 "register_operand" "=r,r")(plus:SI (match_operand:SI 1 "register_operand" "%r,r")(match_operand:SI 2 "nonmemory_operand" "r,I")))]"""@l.add \t%0,%1,%2l.addi \t%0,%1,%2"[(set_attr "type" "add,add")(set_attr "length" "1,1")])(define_insn "subsi3"[(set (match_operand:SI 0 "register_operand" "=r,r")(minus:SI (match_operand:SI 1 "register_operand" "r,r")(match_operand:SI 2 "nonmemory_operand" "r,I")))]"""@l.sub \t%0,%1,%2l.addi \t%0,%1,%n2"[(set_attr "type" "add,add")]);;;; mul and div;;(define_insn "mulsi3"[(set (match_operand:SI 0 "register_operand" "=r")(mult:SI (match_operand:SI 1 "register_operand" "r")(match_operand:SI 2 "register_operand" "r")))]"TARGET_HARD_MUL""l.mul \t%0,%1,%2"[(set_attr "type" "mul")(set_attr "length" "1")])(define_insn "divsi3"[(set (match_operand:SI 0 "register_operand" "=r")(div:SI (match_operand:SI 1 "register_operand" "r")(match_operand:SI 2 "register_operand" "r")))]"TARGET_HARD_DIV""l.div \t%0,%1,%2"[(set_attr "type" "mul")(set_attr "length" "1")])(define_insn "udivsi3"[(set (match_operand:SI 0 "register_operand" "=r")(udiv:SI (match_operand:SI 1 "register_operand" "r")(match_operand:SI 2 "register_operand" "r")))]"TARGET_HARD_DIV""l.divu \t%0,%1,%2"[(set_attr "type" "mul")(set_attr "length" "1")]);;;; jumps;;;; jump(define_expand "jump"[(set (pc)(label_ref (match_operand 0 "" "")))]"""{emit_jump_insn (gen_jump_internal (operands[0]));DONE;}")(define_insn "jump_internal"[(set (pc)(label_ref (match_operand 0 "" "")))]"""l.j \t%l0%("[(set_attr "type" "jump")(set_attr "length" "1")]);; indirect jump(define_expand "indirect_jump"[(set (pc) (match_operand:SI 0 "register_operand" "r"))]"""{emit_jump_insn (gen_indirect_jump_internal (operands[0]));DONE;}")(define_insn "indirect_jump_internal"[(set (pc) (match_operand:SI 0 "register_operand" "r"))]"""l.jr \t%0%("[(set_attr "type" "jump")(set_attr "length" "1")]);;;; calls;;;; call(define_expand "call"[(parallel [(call (match_operand:SI 0 "sym_ref_mem_operand" "")(match_operand 1 "" "i"))(clobber (reg:SI 9))])]"""{emit_call_insn (gen_call_internal (operands[0], operands[1]));DONE;}")(define_insn "call_internal"[(parallel [(call (match_operand:SI 0 "sym_ref_mem_operand" "")(match_operand 1 "" "i"))(clobber (reg:SI 9))])]"""l.jal \t%S0%("[(set_attr "type" "jump")(set_attr "length" "1")]);; call value(define_expand "call_value"[(parallel [(set (match_operand 0 "register_operand" "=r")(call (match_operand:SI 1 "sym_ref_mem_operand" "")(match_operand 2 "" "i")))(clobber (reg:SI 9))])]"""{emit_call_insn (gen_call_value_internal (operands[0], operands[1], operands[2]));DONE;}")(define_insn "call_value_internal"[(parallel [(set (match_operand 0 "register_operand" "=r")(call (match_operand:SI 1 "sym_ref_mem_operand" "")(match_operand 2 "" "i")))(clobber (reg:SI 9))])]"""l.jal \t%S1%("[(set_attr "type" "jump")(set_attr "length" "1")]);; indirect call value(define_expand "call_value_indirect"[(parallel [(set (match_operand 0 "register_operand" "=r")(call (mem:SI (match_operand:SI 1 "register_operand" "r"))(match_operand 2 "" "i")))(clobber (reg:SI 9))])]"""{emit_call_insn (gen_call_value_indirect_internal (operands[0], operands[1], operands[2]));DONE;}")(define_insn "call_value_indirect_internal"[(parallel [(set (match_operand 0 "register_operand" "=r")(call (mem:SI (match_operand:SI 1 "register_operand" "r"))(match_operand 2 "" "i")))(clobber (reg:SI 9))])]"""l.jalr \t%1%("[(set_attr "type" "jump")(set_attr "length" "1")]);; indirect call(define_expand "call_indirect"[(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))(match_operand 1 "" "i"))(clobber (reg:SI 9))])]"""{emit_call_insn (gen_call_indirect_internal (operands[0], operands[1]));DONE;}")(define_insn "call_indirect_internal"[(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))(match_operand 1 "" "i"))(clobber (reg:SI 9))])]"""l.jalr \t%0%("[(set_attr "type" "jump")(set_attr "length" "1")]);; table jump(define_expand "tablejump"[(set (pc) (match_operand:SI 0 "register_operand" "r"))(use (label_ref (match_operand 1 "" "")))]"""{if (CASE_VECTOR_PC_RELATIVE || flag_pic)operands[0]= force_reg (Pmode,gen_rtx_PLUS (Pmode, operands[0],gen_rtx_LABEL_REF (Pmode, operands[1])));emit_jump_insn (gen_tablejump_internal (operands[0], operands[1]));DONE;}")(define_insn "tablejump_internal"[(set (pc) (match_operand:SI 0 "register_operand" "r"))(use (label_ref (match_operand 1 "" "")))]"""l.jr \t%0%("[(set_attr "type" "jump")(set_attr "length" "1")]);; no-op(define_insn "nop"[(const_int 0)]"""l.nop"[(set_attr "type" "logic")(set_attr "length" "1")]);;;; floating point;;;; floating point arithmetic(define_insn "addsf3"[(set (match_operand:SF 0 "register_operand" "=r")(plus:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")))]"TARGET_HARD_FLOAT""lf.add.s\t%0,%1,%2"[(set_attr "type" "fp")(set_attr "length" "1")])(define_insn "adddf3"[(set (match_operand:DF 0 "register_operand" "=r")(plus:DF (match_operand:DF 1 "register_operand" "r")(match_operand:DF 2 "register_operand" "r")))]"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT""lf.add.d\t%0,%1,%2"[(set_attr "type" "fp")(set_attr "length" "1")])(define_insn "subsf3"[(set (match_operand:SF 0 "register_operand" "=r")(minus:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")))]"TARGET_HARD_FLOAT""lf.sub.s\t%0,%1,%2"[(set_attr "type" "fp")(set_attr "length" "1")])(define_insn "subdf3"[(set (match_operand:DF 0 "register_operand" "=r")(minus:DF (match_operand:DF 1 "register_operand" "r")(match_operand:DF 2 "register_operand" "r")))]"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT""lf.sub.d\t%0,%1,%2"[(set_attr "type" "fp")(set_attr "length" "1")])(define_insn "mulsf3"[(set (match_operand:SF 0 "register_operand" "=r")(mult:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")))]"TARGET_HARD_FLOAT""lf.mul.s\t%0,%1,%2"[(set_attr "type" "fp")(set_attr "length" "1")])(define_insn "muldf3"[(set (match_operand:DF 0 "register_operand" "=r")(mult:DF (match_operand:DF 1 "register_operand" "r")(match_operand:DF 2 "register_operand" "r")))]"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT""lf.mul.d\t%0,%1,%2"[(set_attr "type" "fp")(set_attr "length" "1")])(define_insn "divsf3"[(set (match_operand:SF 0 "register_operand" "=r")(div:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")))]"TARGET_HARD_FLOAT""lf.div.s\t%0,%1,%2"[(set_attr "type" "fp")(set_attr "length" "1")])(define_insn "divdf3"[(set (match_operand:DF 0 "register_operand" "=r")(div:DF (match_operand:DF 1 "register_operand" "r")(match_operand:DF 2 "register_operand" "r")))]"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT""lf.div.d\t%0,%1,%2"[(set_attr "type" "fp")(set_attr "length" "1")]);; Conversion between fixed point and floating point.(define_insn "floatsisf2"[(set (match_operand:SF 0 "register_operand" "=r")(float:SF (match_operand:SI 1 "register_operand" "r")))]"TARGET_HARD_FLOAT""lf.itof.s\t%0, %1"[(set_attr "type" "fp")(set_attr "length" "1")]);; not working(define_insn "fixunssfsi2"[(set (match_operand:SI 0 "register_operand" "=r")(fix:SI (match_operand:SF 1 "register_operand" "r")))]"TARGET_HARD_FLOAT""lf.ftoi.s\t%0, %1"[(set_attr "type" "fp")(set_attr "length" "1")]);; Local variables:;; mode:emacs-lisp;; comment-start: ";; ";; eval: (set-syntax-table (copy-sequence (syntax-table)));; eval: (modify-syntax-entry ?[ "(]");; eval: (modify-syntax-entry ?] ")[");; eval: (modify-syntax-entry ?{ "(}");; eval: (modify-syntax-entry ?} "){");; eval: (setq indent-tabs-mode t);; End:
