@@ -310,6 +310,75 @@ 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+ /**/
326+ addend = (insn << 16 ) >> 22 ;
327+ addend = addend << 10 ;
328+ addend |= ((insn << 5 ) >> 22 );
329+ addend = addend << 1 ;
330+
331+ /* (S + A) - P */
332+ S = (uintptr_t )(uint8 * )symbol_addr ;
333+ A = (intptr_t )reloc_addend ;
334+ P = (uintptr_t )(target_section_addr + reloc_offset );
335+ P &= (uintptr_t )~1 ;
336+ value = (int32 )(S + A + addend - P );
337+
338+ insn = insn & 0xf801003f ;
339+ insn |= ((((value >> 1 ) & 0x3ff ) << 17 )
340+ | (((value >> 1 ) & 0xffc00 ) >> 4 ));
341+
342+ /* Convert to middle endian */
343+ insn = middle_endian_convert (insn );
344+
345+ STORE_U32 (target_section_addr + reloc_offset , insn );
346+ break ;
347+ }
348+ case R_ARC_S21W_PCREL :
349+ {
350+ uint32 insn = LOAD_I32 (target_section_addr + reloc_offset );
351+ int32 addend , value ;
352+ uintptr_t S , P ;
353+ intptr_t A ;
354+
355+ CHECK_RELOC_OFFSET (sizeof (void * ));
356+
357+ /* Convert from middle endian */
358+ insn = middle_endian_convert (insn );
359+
360+ addend = (insn << 16 ) >> 22 ;
361+ addend = addend << 9 ;
362+ addend |= ((insn << 5 ) >> 23 );
363+ addend = addend << 2 ;
364+
365+ /* (S + A) - P */
366+ S = (uintptr_t )(uint8 * )symbol_addr ;
367+ A = (intptr_t )reloc_addend ;
368+ P = (uintptr_t )(target_section_addr + reloc_offset );
369+ P &= (uintptr_t )~3 ;
370+ value = (int32 )(S + A + addend - P );
371+
372+ insn = insn & 0xf803003f ;
373+ insn |= ((((value >> 2 ) & 0x1ff ) << 18 )
374+ | (((value >> 2 ) & 0x7fe00 ) >> 3 ));
375+
376+ /* Convert to middle endian */
377+ insn = middle_endian_convert (insn );
378+
379+ STORE_U32 (target_section_addr + reloc_offset , insn );
380+ break ;
381+ }
313382 case R_ARC_S25H_PCREL :
314383 {
315384 uint32 insn = LOAD_I32 (target_section_addr + reloc_offset );
@@ -340,8 +409,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
340409
341410 insn = insn & 0xf8010030 ;
342411 insn |= ((((value >> 1 ) & 0x3ff ) << 17 )
343- | (((value >> 1 ) & 0xffc00 ) >> 3 )
344- | (((value >> 1 ) & 0xf00000 ) >> 19 ));
412+ | (((value >> 1 ) & 0xffc00 ) >> 4 )
413+ | (((value >> 1 ) & 0xf00000 ) >> 20 ));
345414
346415 /* Convert to middle endian */
347416 insn = middle_endian_convert (insn );
0 commit comments