@@ -59,6 +59,7 @@ static void cp_byval_mem_arg(int);
5959static int allochartmp (int lenili );
6060static int block_str_move (STRDESC * , STRDESC * );
6161static int getchartmp (int ili );
62+ static void _exp_smove (int , int , int , int , DTYPE );
6263
6364void arg_is_refd (int ); /* FIXME? move from llassem.c? */
6465
@@ -132,6 +133,21 @@ getstrlen64(STRDESC *str)
132133 return il ;
133134}
134135
136+ /*
137+ * Generating GSMOVE ILI is under XBIT(2,0x800000). When the XBIT is not
138+ * set, _exp_smove() will proceed as before; in particular, chk_block() is
139+ * called to add terminal ILI to the block current to the expander. When
140+ * the XBIT is set, the GSMOVE ili are transformed sometime after the expander,
141+ * but we still want the code in _exp_smove() to do the work. However, we
142+ * cannot call chk_block() to add the terminal ILI; we must use 'addilt'.
143+ * So, define and use a function pointer, p_chk_block, which calls either
144+ * chk_block() or a new local addilit routine, gsmove_chk_block(). In this
145+ * case, the current ilt is saved as the file static, gsmove_ilt.
146+ */
147+ static void (* p_chk_block )(int ) = chk_block ;
148+ static void gsmove_chk_block (int );
149+ static int gsmove_ilt ;
150+
135151/* aux.curr_entry->flags description:
136152 * Initialized to 0 by exp_end
137153 * NA 0x1 - need to save argument registers (set by exp_end).
@@ -4202,6 +4218,61 @@ expand_smove(int destilm, int srcilm, DTYPE dtype)
42024218 }
42034219 dest_addr = ILI_OF (destilm );
42044220 src_addr = ILI_OF (srcilm );
4221+ if (USE_GSMOVE ) {
4222+ int ilix ;
4223+ ilix = ad5ili (IL_GSMOVE , src_addr , dest_addr , src_nme , dest_nme , dtype );
4224+ chk_block (ilix );
4225+ }
4226+ else {
4227+ _exp_smove (dest_nme , src_nme , dest_addr , src_addr , dtype );
4228+ }
4229+ }
4230+
4231+ /** \brief Transform the GSMOVE ILI created by expand_smove()
4232+ */
4233+ void
4234+ exp_remove_gsmove (void )
4235+ {
4236+ int bihx , iltx , ilix ;
4237+ p_chk_block = gsmove_chk_block ;
4238+ for (bihx = gbl .entbih ; bihx ; bihx = BIH_NEXT (bihx )) {
4239+ int next_ilt ;
4240+ LOGICAL any_gsmove = FALSE;
4241+ rdilts (bihx );
4242+ for (iltx = ILT_NEXT (0 ); iltx ; ) {
4243+ next_ilt = ILT_NEXT (iltx );
4244+ ilix = ILT_ILIP (iltx );
4245+ if (ILI_OPC (ilix ) == IL_GSMOVE ) {
4246+ int src_addr = ILI_OPND (ilix , 1 );
4247+ int dest_addr = ILI_OPND (ilix , 2 );
4248+ int src_nme = ILI_OPND (ilix , 3 );
4249+ int dest_nme = ILI_OPND (ilix , 4 );
4250+ DTYPE dtype = ILI_OPND (ilix , 5 );
4251+ any_gsmove = TRUE;
4252+ gsmove_ilt = iltx ;
4253+ _exp_smove (dest_nme , src_nme , dest_addr , src_addr , dtype );
4254+ ILT_NEXT (gsmove_ilt ) = next_ilt ;
4255+ ILT_PREV (next_ilt ) = gsmove_ilt ;
4256+ delilt (iltx );
4257+ }
4258+ iltx = next_ilt ;
4259+ }
4260+ wrilts (bihx );
4261+ if (DBGBIT (10 ,2 ) && any_gsmove ) {
4262+ fprintf (gbl .dbgfil , "\n***** After remove gsmove *****\n" );
4263+ dump_one_block (gbl .dbgfil , bihx , NULL );
4264+ }
4265+ }
4266+ p_chk_block = chk_block ;
4267+ }
4268+
4269+ static void
4270+ _exp_smove (int dest_nme , int src_nme , int dest_addr , int src_addr , DTYPE dtype )
4271+ {
4272+ ISZ_T n ; /* number of bytes left to copy */
4273+ int i ;
4274+ INT offset ; /* number of bytes from begin addr */
4275+
42054276 n = size_of (dtype );
42064277 offset = 0 ;
42074278
@@ -4211,10 +4282,10 @@ expand_smove(int destilm, int srcilm, DTYPE dtype)
42114282 if (n > TEST_BOUND ) {
42124283
42134284 if (XBIT (2 , 0x200000 )) {
4214- chk_block (ad4ili (IL_SMOVE , src_addr , dest_addr , ad_aconi (n / SMOVE_CHUNK ),
4285+ p_chk_block (ad4ili (IL_SMOVE , src_addr , dest_addr , ad_aconi (n / SMOVE_CHUNK ),
42154286 dest_nme ));
42164287 } else {
4217- chk_block (ad4ili (IL_SMOVEI , ad2ili (IL_SMOVES , src_addr , src_nme ),
4288+ p_chk_block (ad4ili (IL_SMOVEI , ad2ili (IL_SMOVES , src_addr , src_nme ),
42184289 dest_addr , n , dest_nme ));
42194290 }
42204291 smove_flag = 1 ; /* structure move in this function */
@@ -4255,7 +4326,7 @@ expand_smove(int destilm, int srcilm, DTYPE dtype)
42554326 ilip = ad4ili (IL_STKR , ilix , ilip , dest_nme , siz );
42564327 else
42574328 ilip = ad4ili (IL_ST , ilix , ilip , dest_nme , siz );
4258- chk_block (ilip );
4329+ p_chk_block (ilip );
42594330
42604331 offset += skip ;
42614332 n -= skip ;
@@ -5317,6 +5388,15 @@ exp_reset_argregs(int ir, int fr)
53175388{
53185389}
53195390
5391+ /**
5392+ * \brief Create & add an ILT for an ILI when transforming GSMOVE ILI
5393+ */
5394+ static void
5395+ gsmove_chk_block (int ili )
5396+ {
5397+ gsmove_ilt = addilt (gsmove_ilt , ili );
5398+ }
5399+
53205400/*------------------------------------------------------------------*/
53215401
53225402#undef ILM_OPC
0 commit comments