@@ -310,6 +310,80 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
310310 int32 symbol_index , char * error_buf , uint32 error_buf_size )
311311{
312312 switch (reloc_type ) {
313+ case R_ARC_S21H_PCREL :
314+ {
315+ uint32 insn = LOAD_I32 (target_section_addr + reloc_offset );
316+ int32 addend , value ;
317+ uintptr_t S , P ;
318+ intptr_t A ;
319+
320+ CHECK_RELOC_OFFSET (sizeof (void * ));
321+
322+ /* Convert from middle endian */
323+ insn = middle_endian_convert (insn );
324+
325+ /* Extract the first 10 bits from Position 6 to 15 in insn */
326+ addend = (insn << 16 ) >> 22 ;
327+ addend = addend << 10 ;
328+ /* Extract the remaining 10 bits from Position 17 to 26 in insn */
329+ addend |= ((insn << 5 ) >> 22 );
330+ /* Fill in 1 bits to get the 21 bit Offset Value */
331+ addend = addend << 1 ;
332+
333+ /* (S + A) - P */
334+ S = (uintptr_t )(uint8 * )symbol_addr ;
335+ A = (intptr_t )reloc_addend ;
336+ P = (uintptr_t )(target_section_addr + reloc_offset );
337+ P &= (uintptr_t )~1 ;
338+ value = (int32 )(S + A + addend - P );
339+
340+ insn = insn & 0xf801003f ;
341+ insn |= ((((value >> 1 ) & 0x3ff ) << 17 )
342+ | (((value >> 1 ) & 0xffc00 ) >> 4 ));
343+
344+ /* Convert to middle endian */
345+ insn = middle_endian_convert (insn );
346+
347+ STORE_U32 (target_section_addr + reloc_offset , insn );
348+ break ;
349+ }
350+ case R_ARC_S21W_PCREL :
351+ {
352+ uint32 insn = LOAD_I32 (target_section_addr + reloc_offset );
353+ int32 addend , value ;
354+ uintptr_t S , P ;
355+ intptr_t A ;
356+
357+ CHECK_RELOC_OFFSET (sizeof (void * ));
358+
359+ /* Convert from middle endian */
360+ insn = middle_endian_convert (insn );
361+
362+ /* Extract the first 10 bits from Position 6 to 15 in insn */
363+ addend = (insn << 16 ) >> 22 ;
364+ addend = addend << 9 ;
365+ /* Extract the remaining 9 bits from Position 18 to 26 in insn */
366+ addend |= ((insn << 5 ) >> 23 );
367+ /* Fill in 2 bits to get the 21 bit Offset Value */
368+ addend = addend << 2 ;
369+
370+ /* (S + A) - P */
371+ S = (uintptr_t )(uint8 * )symbol_addr ;
372+ A = (intptr_t )reloc_addend ;
373+ P = (uintptr_t )(target_section_addr + reloc_offset );
374+ P &= (uintptr_t )~3 ;
375+ value = (int32 )(S + A + addend - P );
376+
377+ insn = insn & 0xf803003f ;
378+ insn |= ((((value >> 2 ) & 0x1ff ) << 18 )
379+ | (((value >> 2 ) & 0x7fe00 ) >> 3 ));
380+
381+ /* Convert to middle endian */
382+ insn = middle_endian_convert (insn );
383+
384+ STORE_U32 (target_section_addr + reloc_offset , insn );
385+ break ;
386+ }
313387 case R_ARC_S25H_PCREL :
314388 {
315389 uint32 insn = LOAD_I32 (target_section_addr + reloc_offset );
@@ -340,8 +414,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
340414
341415 insn = insn & 0xf8010030 ;
342416 insn |= ((((value >> 1 ) & 0x3ff ) << 17 )
343- | (((value >> 1 ) & 0xffc00 ) >> 3 )
344- | (((value >> 1 ) & 0xf00000 ) >> 19 ));
417+ | (((value >> 1 ) & 0xffc00 ) >> 4 )
418+ | (((value >> 1 ) & 0xf00000 ) >> 20 ));
345419
346420 /* Convert to middle endian */
347421 insn = middle_endian_convert (insn );
0 commit comments