152284Sobrien/* Insert USEs in instructions that require mode switching. 2169689Skan This should probably be merged into mode-switching.cc . 3117395Skan Copyright (C) 2011-2022 Free Software Foundation, Inc. 452284Sobrien Contributed by Embecosm on behalf of Adapteva, Inc. 5132718Skan 652284SobrienThis file is part of GCC. 7132718Skan 852284SobrienGCC is free software; you can redistribute it and/or modify 952284Sobrienit under the terms of the GNU General Public License as published by 1052284Sobrienthe Free Software Foundation; either version 3, or (at your option) 1152284Sobrienany later version. 12132718Skan 1352284SobrienGCC is distributed in the hope that it will be useful, 1452284Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1552284SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1652284SobrienGNU General Public License for more details. 1752284Sobrien 18132718SkanYou should have received a copy of the GNU General Public License 19169689Skanalong with GCC; see the file COPYING3. If not see 20169689Skan<http://www.gnu.org/licenses/>. */ 2152284Sobrien 2290075Sobrien#define IN_TARGET_CODE 1 23117395Skan 2490075Sobrien#include "config.h" 2590075Sobrien#include "system.h" 2652284Sobrien#include "coretypes.h" 2752284Sobrien#include "backend.h" 28117395Skan#include "rtl.h" 2952284Sobrien#include "df.h" 3052284Sobrien#include "memmodel.h" 3152284Sobrien#include "tm_p.h" 3252284Sobrien#include "emit-rtl.h" 3390075Sobrien#include "tree-pass.h" 3490075Sobrien#include "insn-attr.h" 3590075Sobrien 3690075Sobrien#ifndef TARGET_INSERT_MODE_SWITCH_USE 3790075Sobrien#define TARGET_INSERT_MODE_SWITCH_USE NULL 3890075Sobrien#endif 3990075Sobrien 4090075Sobrienstatic unsigned int 4190075Sobrieninsert_uses (void) 4290075Sobrien{ 4390075Sobrien static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING; 4490075Sobrien#define N_ENTITIES ARRAY_SIZE (num_modes) 4590075Sobrien int e; 4690075Sobrien void (*target_insert_mode_switch_use) (rtx_insn *insn, int, int) 4790075Sobrien = TARGET_INSERT_MODE_SWITCH_USE; 4890075Sobrien 4990075Sobrien for (e = N_ENTITIES - 1; e >= 0; e--) 5090075Sobrien { 5152284Sobrien int no_mode = num_modes[e]; 5252284Sobrien rtx_insn *insn; 5390075Sobrien int mode; 5452284Sobrien 5552284Sobrien if (!OPTIMIZE_MODE_SWITCHING (e)) 5690075Sobrien continue; 5790075Sobrien for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 5890075Sobrien { 5952284Sobrien if (!INSN_P (insn)) 60132718Skan continue; 6190075Sobrien mode = epiphany_mode_needed (e, insn); 62132718Skan if (mode == no_mode) 6390075Sobrien continue; 6490075Sobrien if (target_insert_mode_switch_use) 6590075Sobrien { 6690075Sobrien target_insert_mode_switch_use (insn, e, mode); 6790075Sobrien df_insn_rescan (insn); 6890075Sobrien } 6990075Sobrien } 7090075Sobrien } 7190075Sobrien return 0; 7290075Sobrien} 7390075Sobrien 7490075Sobriennamespace { 7590075Sobrien 7652284Sobrienconst pass_data pass_data_mode_switch_use = 7752284Sobrien{ 7852284Sobrien RTL_PASS, /* type */ 7952284Sobrien "mode_switch_use", /* name */ 8052284Sobrien OPTGROUP_NONE, /* optinfo_flags */ 81117395Skan TV_NONE, /* tv_id */ 82117395Skan 0, /* properties_required */ 83117395Skan 0, /* properties_provided */ 84117395Skan 0, /* properties_destroyed */ 85117395Skan 0, /* todo_flags_start */ 86117395Skan 0, /* todo_flags_finish */ 87117395Skan}; 88117395Skan 8952284Sobrienclass pass_mode_switch_use : public rtl_opt_pass 9090075Sobrien{ 9190075Sobrienpublic: 92117395Skan pass_mode_switch_use(gcc::context *ctxt) 9390075Sobrien : rtl_opt_pass(pass_data_mode_switch_use, ctxt) 9490075Sobrien {} 9552284Sobrien 9652284Sobrien /* opt_pass methods: */ 9752284Sobrien virtual unsigned int execute (function *) { return insert_uses (); } 9852284Sobrien 9952284Sobrien}; // class pass_mode_switch_use 10052284Sobrien 10152284Sobrien} // anon namespace 10252284Sobrien 10352284Sobrienrtl_opt_pass * 10452284Sobrienmake_pass_mode_switch_use (gcc::context *ctxt) 10552284Sobrien{ 10652284Sobrien return new pass_mode_switch_use (ctxt); 10752284Sobrien} 10852284Sobrien