Changeset 11754


Ignore:
Timestamp:
Feb 22, 2009, 10:40:45 AM (10 years ago)
Author:
gb
Message:

The lisp assembler generates slightly different code than GAS does for
x8632 instructions that have a memory operand that contains only a
32-bit displacement (but no scale factor or index/base registers.)
pc_luser_xp() expects the shorter encodings for those affected
instructions that're used in the consing sequence, and may therefore
adjust the PC of a thread that's interrupted during consing by too few
bytes if a longer-than-expected instruction is used.

If LISP_ASSEMBLER_EXTRA_SIB_BYTE is defined, try to detect cases where
this extra byte is present and account for it when adjusting the PC
of any thread interrupted in the middle of allocation.

LISP_ASSEMBLER_EXTRA_SIB_BYTE is defined on x8632; if/when we fix
the assembler and bootstrap that change, we can stop defining it
and remove the conditionalized code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/x86-exceptions.c

    r11741 r11754  
    23392339#endif
    23402340#ifdef X8632
     2341/* The lisp assembler might use both a modrm byte and a sib byte to
     2342   encode a memory operand that contains a displacement but no
     2343   base or index.  Using the sib byte is necessary for 64-bit code,
     2344   since the sib-less form is used to indicate %rip-relative addressing
     2345   on x8664.  On x8632, it's not necessary, slightly suboptimal, and
     2346   doesn't match what we expect; until that's fixed, we may need to
     2347   account for this extra byte when adjusting the PC */
     2348#define LISP_ASSEMBLER_EXTRA_SIB_BYTE
    23412349#ifdef WIN32_ES_HACK
    23422350/* Win32 keeps the TCR in %es */
     
    23472355#endif
    23482356opcode load_allocptr_reg_from_tcr_save_allocptr_instruction[] =
    2349   {TCR_SEG_PREFIX,0x8b,0x0d,0x84,0x00,0x00,0x00};
     2357  {TCR_SEG_PREFIX,0x8b,0x0d,0x84,0x00,0x00,0x00};  /* may have extra SIB byte */
    23502358opcode compare_allocptr_reg_to_tcr_save_allocbase_instruction[] =
    2351   {TCR_SEG_PREFIX,0x3b,0x0d,0x88,0x00,0x00,0x00};
     2359  {TCR_SEG_PREFIX,0x3b,0x0d,0x88,0x00,0x00,0x00};  /* may have extra SIB byte */
    23522360opcode branch_around_alloc_trap_instruction[] =
    2353   {0x77,0x02};
     2361  {0x77,0x02};                  /* no SIB byte issue */
    23542362opcode alloc_trap_instruction[] =
    2355   {0xcd,0xc5};
     2363  {0xcd,0xc5};                  /* no SIB byte issue */
    23562364opcode clear_tcr_save_allocptr_tag_instruction[] =
    2357   {TCR_SEG_PREFIX,0x80,0x25,0x84,0x00,0x00,0x00,0xf8};
     2365  {TCR_SEG_PREFIX,0x80,0x25,0x84,0x00,0x00,0x00,0xf8}; /* maybe SIB byte */
    23582366opcode set_allocptr_header_instruction[] =
    2359   {0x0f,0x7e,0x41,0xfa};
     2367  {0x0f,0x7e,0x41,0xfa};        /* no SIB byte issue */
    23602368
    23612369alloc_instruction_id
     
    23912399      sizeof(cons) - fulltag_cons :
    23922400#ifdef X8664
    2393       xpGPR(xp,Iimm1);
    2394 #else
    2395       xpGPR(xp,Iimm0);
    2396 #endif
     2401      xpGPR(xp,Iimm1)
     2402#else
     2403      xpGPR(xp,Iimm0)
     2404#endif
     2405      ;
    23972406    LispObj new_vector;
    23982407
     
    24162425#endif
    24172426        ;
    2418 
     2427     
    24192428      xpPC(xp) += sizeof(set_allocptr_header_instruction);
     2429
    24202430      /* Fall thru */
    24212431    case ID_clear_tcr_save_allocptr_tag_instruction:
    24222432      tcr->save_allocptr = (void *)(((LispObj)tcr->save_allocptr) & ~fulltagmask);
     2433#ifdef LISP_ASSEMBLER_EXTRA_SIB_BYTE
     2434      if (((pc)(xpPC(xp)))[2] == 0x24) {
     2435        xpPC(xp) += 1;
     2436      }
     2437#endif
    24232438      xpPC(xp) += sizeof(clear_tcr_save_allocptr_tag_instruction);
     2439
    24242440      break;
    24252441    case ID_alloc_trap_instruction:
     
    24372453        xpGPR(xp,Iallocptr) = VOID_ALLOCPTR;
    24382454        tcr->save_allocptr += disp;
     2455#ifdef LISP_ASSEMBLER_EXTRA_SIB_BYTE
     2456        /* This assumes that TCR_SEG_PREFIX can't appear
     2457           anywhere but at the beginning of one of these
     2458           magic allocation-sequence instructions. */
     2459        xpPC(xp) -= (sizeof(branch_around_alloc_trap_instruction)+
     2460                     sizeof(compare_allocptr_reg_to_tcr_save_allocbase_instruction));
     2461        if (*((pc)(xpPC(xp))) == TCR_SEG_PREFIX) {
     2462          xpPC(xp) -= sizeof(load_allocptr_reg_from_tcr_save_allocptr_instruction);
     2463        } else {
     2464          xpPC(xp) -= (sizeof(load_allocptr_reg_from_tcr_save_allocptr_instruction) + 2);
     2465        }
     2466       
     2467#else
    24392468        xpPC(xp) -= (sizeof(branch_around_alloc_trap_instruction)+
    24402469                     sizeof(compare_allocptr_reg_to_tcr_save_allocbase_instruction) +
    24412470                     sizeof(load_allocptr_reg_from_tcr_save_allocptr_instruction));
     2471#endif
    24422472      }
    24432473      break;
     
    24612491          }
    24622492          tcr->save_allocptr = (void *)(((LispObj)tcr->save_allocptr) & ~fulltagmask);
     2493#ifdef LISP_ASSEMBLER_EXTRA_SIB_BYTE
     2494          if (((pc)xpPC(xp))[2] == 0x24) {
     2495            xpPC(xp) += 1;
     2496          }
     2497#endif
    24632498          xpPC(xp) += sizeof(clear_tcr_save_allocptr_tag_instruction);
    24642499        } else {
     
    24662501          xpPC(xp) -= (sizeof(compare_allocptr_reg_to_tcr_save_allocbase_instruction) +
    24672502                       sizeof(load_allocptr_reg_from_tcr_save_allocptr_instruction));
     2503#ifdef LISP_ASSEMBLER_EXTRA_SIB_BYTE
     2504          if (*((pc)(xpPC(xp))) != TCR_SEG_PREFIX) {
     2505            /* skipped two instructions with extra SIB byte */
     2506            xpPC(xp) -= 2;
     2507          }
     2508#endif
    24682509          xpGPR(xp,Iallocptr) = VOID_ALLOCPTR;
    24692510          if (interrupt_displacement) {
     
    24792520      xpGPR(xp,Iallocptr) = VOID_ALLOCPTR;
    24802521      xpPC(xp) -= sizeof(load_allocptr_reg_from_tcr_save_allocptr_instruction);
     2522#ifdef LISP_ASSEMBLER_EXTRA_SIB_BYTE
     2523      if (*((pc)xpPC(xp)) != TCR_SEG_PREFIX) {
     2524        xpPC(xp) -= 1;
     2525      }
     2526#endif
    24812527      /* Fall through */
    24822528    case ID_load_allocptr_reg_from_tcr_save_allocptr_instruction:
Note: See TracChangeset for help on using the changeset viewer.