~ubuntu-branches/ubuntu/trusty/mit-scheme/trusty-proposed

« back to all changes in this revision

Viewing changes to src/microcode/cmpintmd/mips.h

  • Committer: Bazaar Package Importer
  • Author(s): Evan Broder
  • Date: 2009-03-08 00:46:17 UTC
  • mfrom: (1.1.6 upstream) (3.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090308004617-csqyjpnkg7daq9c4
Tags: 7.7.90+20090107-1ubuntu1
* Merge from debian unstable, remaining changes (LP: #288000, #217792):
  * Bootstrapping done via binary package from Debian unstable. See log
      entry for 7.7.90+20060906-3ubuntu1 for details.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*-C-*-
2
2
 
3
 
$Id: mips.h,v 1.27 2007/01/05 21:19:26 cph Exp $
 
3
$Id: mips.h,v 1.29 2008/01/30 20:02:24 cph Exp $
4
4
 
5
5
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
6
6
    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
7
 
    2006, 2007 Massachusetts Institute of Technology
 
7
    2006, 2007, 2008 Massachusetts Institute of Technology
8
8
 
9
9
This file is part of MIT/GNU Scheme.
10
10
 
34
34
 * Specialized for the MIPS R2000/R3000
35
35
 */
36
36
 
37
 
#ifndef CMPINTMD_H_INCLUDED
38
 
#define CMPINTMD_H_INCLUDED
39
 
 
40
 
#include "cmptype.h"
 
37
#ifndef SCM_CMPINTMD_H_INCLUDED
 
38
#define SCM_CMPINTMD_H_INCLUDED 1
41
39
 
42
40
#ifdef _IRIX
43
41
 
98
96
 
99
97
/* Processor type.  Choose a number from the above list, or allocate your own. */
100
98
 
101
 
#define COMPILER_PROCESSOR_TYPE                 COMPILER_MIPS_TYPE
 
99
#define COMPILER_PROCESSOR_TYPE COMPILER_MIPS_TYPE
102
100
 
103
101
/* Size (in long words) of the contents of a floating point register if
104
102
   different from a double.  For example, an MC68881 saves registers
107
105
   define COMPILER_TEMP_SIZE                    3
108
106
*/
109
107
 
 
108
#define COMPILER_REGBLOCK_N_TEMPS 256
 
109
 
110
110
/* Descriptor size.
111
111
   This is the size of the offset field, and of the format field.
112
112
   This definition probably does not need to be changed.
113
113
 */
114
114
 
115
115
typedef unsigned short format_word;
116
 
 
117
 
/* PC alignment constraint.
118
 
   Change PC_ZERO_BITS to be how many low order bits of the pc are
119
 
   guaranteed to be 0 always because of PC alignment constraints.
120
 
*/
121
 
 
122
 
#define PC_ZERO_BITS                    2
123
116
 
124
117
/* Utilities for manipulating absolute subroutine calls.
125
118
   On the MIPS this is done with:
199
192
  SLT   $at,$FREE,$MEMTOP
200
193
  BEQ   $at,$0,interrupt
201
194
  LW    $MEMTOP,REG_BLOCK
202
 
  
 
195
 
203
196
  For a closure
204
197
 
205
198
  LUI   $at,FROB(TC_CLOSURE)    ; temp <- closure tag
225
218
 
226
219
   On the MIPS this is 2 format_words for the format word and gc
227
220
   offset words, and 8 more bytes for 2 instructions.
228
 
   
 
221
 
229
222
   The two instructions are
230
223
 
231
224
   JAL  destination
236
229
   not always work, thus closures are allocated from a pre-initialized
237
230
   pool where the entries have been initialized to contain
238
231
   the following instructions.
239
 
   
 
232
 
240
233
   JALR LINKAGE,CLOSURE_HOOK
241
234
   ADDI LINKAGE,LINKAGE,-8
242
235
 
320
313
 
321
314
#define TRAMPOLINE_STORAGE(tramp_entry)                                 \
322
315
  ((((SCHEME_OBJECT *) (tramp_entry)) - TRAMPOLINE_BLOCK_TO_ENTRY) +    \
323
 
   (2 + TRAMPOLINE_ENTRY_SIZE)) 
 
316
   (2 + TRAMPOLINE_ENTRY_SIZE))
324
317
 
325
318
#define SPECIAL_OPCODE  000
326
319
#define ADDI_OPCODE     010
361
354
   arguments in the lower 16 bits.
362
355
 */
363
356
 
364
 
#define EXECUTE_CACHE_ENTRY_SIZE        2
 
357
#define EXECUTE_CACHE_ENTRY_SIZE 2
365
358
 
366
359
/* Execute cache destructuring. */
367
360
 
467
460
 
468
461
#define FLUSH_I_CACHE() do                                              \
469
462
{                                                                       \
470
 
  FLUSH_BOTH (Constant_Space,                                           \
471
 
              (((unsigned long) Heap_Top)                               \
472
 
               - ((unsigned long) Constant_Space)));                    \
 
463
  FLUSH_BOTH (constant_start,                                           \
 
464
              (((unsigned long) heap_end)                               \
 
465
               - ((unsigned long) constant_start)));                    \
473
466
} while (0)
474
467
 
475
468
/* This flushes a region of the I-cache.
476
469
   It is used after updating an execute cache while running.
477
470
   Not needed during GC because FLUSH_I_CACHE will be used.
478
 
 */   
 
471
 */
479
472
 
480
473
#define FLUSH_I_CACHE_REGION(address, nwords) do                        \
481
474
{                                                                       \
502
495
{                                                                       \
503
496
  unsigned long _addr = ((unsigned long) (address));                    \
504
497
  unsigned long _nbytes = ((sizeof (long)) * (nwords));                 \
505
 
  cacheflush (((PTR) _addr), _nbytes, DCACHE);                          \
506
 
  cacheflush (((PTR) _addr), 1, ICACHE);                                \
507
 
  cacheflush (((PTR) (_addr + (_nbytes - 1))), 1, ICACHE);              \
 
498
  cacheflush (((void *) _addr), _nbytes, DCACHE);                       \
 
499
  cacheflush (((void *) _addr), 1, ICACHE);                             \
 
500
  cacheflush (((void *) (_addr + (_nbytes - 1))), 1, ICACHE);           \
508
501
} while (0)
509
502
 
510
503
#endif /* not USE_MPROTECT_CACHE_FLUSH */
512
505
#ifdef IN_CMPINT_C
513
506
 
514
507
static void
515
 
DEFUN_VOID (interface_initialize_C)
 
508
interface_initialize_C (void)
516
509
{
517
 
  extern void EXFUN (interface_initialize, (void));
 
510
  extern void interface_initialize (void);
518
511
 
519
512
  /* Prevent the OS from "fixing" unaligned accesses.
520
513
     Within Scheme, they are a BUG, and should fault.
539
532
static unsigned long mprotect_size;
540
533
 
541
534
static void
542
 
DEFUN (call_mprotect_1, (start, size), void * start AND unsigned long size)
 
535
call_mprotect_1 (void * start, unsigned long size)
543
536
{
544
537
  if ((mprotect (start, size, VM_PROT_SCHEME)) != 0)
545
538
    {
553
546
 
554
547
#ifdef USE_MPROTECT_CACHE_FLUSH
555
548
void
556
 
DEFUN (call_mprotect, (start, size), void * start AND unsigned long size)
 
549
call_mprotect (void * start, unsigned long size)
557
550
{
558
551
  unsigned long pagesize = (getpagesize ());
559
552
  unsigned long istart = ((unsigned long) start);
563
556
#endif /* USE_MPROTECT_CACHE_FLUSH */
564
557
 
565
558
void *
566
 
DEFUN (irix_heap_malloc, (size), long size)
 
559
irix_heap_malloc (long size)
567
560
{
568
561
  int pagesize = (getpagesize ());
569
562
  void * area = (malloc (size + pagesize));
586
579
 
587
580
static long closure_chunk = (1024 * CLOSURE_ENTRY_WORDS);
588
581
 
589
 
#define REGBLOCK_CLOSURE_LIMIT  REGBLOCK_CLOSURE_SPACE
590
 
 
591
582
/* The apparently random instances of the number 3 below arise from
592
583
   the convention that free_closure always points to a JAL instruction
593
584
   with (at least) 3 unused words preceding it.
594
585
   In this way, if there is enough space, we can use free_closure
595
586
   as the address of a new uni- or multi-closure.
596
 
   
 
587
 
597
588
   The code below (in the initialization loop) depends on knowing that
598
589
   CLOSURE_ENTRY_WORDS is 3.
599
 
   
 
590
 
600
591
   Random hack: ADDI instructions look like TC_TRUE objects, thus of the
601
592
   pre-initialized words, only the JALR looks like a pointer object
602
593
   (an SCODE-QUOTE).  Since there is exactly one JALR of waste between
608
599
/* size in Scheme objects of the block we need to allocate. */
609
600
 
610
601
void
611
 
DEFUN (allocate_closure, (size), long size)
 
602
allocate_closure (long size)
612
603
{
613
604
  long space;
614
605
  SCHEME_OBJECT * free_closure, * limit;
615
606
 
616
 
  free_closure = ((SCHEME_OBJECT *) Registers[REGBLOCK_CLOSURE_FREE]);
617
 
  limit = ((SCHEME_OBJECT *) Registers[REGBLOCK_CLOSURE_LIMIT]);
 
607
  free_closure = GET_CLOSURE_FREE;
 
608
  limit = GET_CLOSURE_SPACE;
618
609
  space =  ((limit - free_closure) + 3);
619
610
 
620
611
  /* Bump up to a multiple of CLOSURE_ENTRY_WORDS.
632
623
    /* Make the heap be parseable forward by protecting the waste
633
624
       in the last chunk.
634
625
     */
635
 
       
 
626
 
636
627
    if ((space > 0) && (free_closure != ((SCHEME_OBJECT *) NULL)))
637
628
      free_closure[-3] = (MAKE_OBJECT (TC_MANIFEST_NM_VECTOR, (space - 1)));
638
629
 
639
630
    free_closure = Free;
640
 
    if ((size <= closure_chunk) && (!(GC_Check (closure_chunk))))
 
631
    if ((size <= closure_chunk) && (!GC_NEEDED_P (closure_chunk)))
641
632
      limit = (free_closure + closure_chunk);
642
633
    else
643
634
    {
644
 
      if (GC_Check (size))
 
635
      if (GC_NEEDED_P (size))
645
636
      {
646
 
        if ((Heap_Top - Free) < size)
 
637
        if ((heap_end - Free) < size)
647
638
        {
648
639
          /* No way to back out -- die. */
649
640
          fprintf (stderr, "\nC_allocate_closure (%d): No space.\n", size);
650
641
          Microcode_Termination (TERM_NO_SPACE);
651
642
          /* NOTREACHED */
652
643
        }
653
 
        Request_GC (0);
 
644
        REQUEST_GC (0);
654
645
      }
655
646
      else if (size <= closure_chunk)
656
 
        Request_GC (0);
 
647
        REQUEST_GC (0);
657
648
      limit = (free_closure + size);
658
649
    }
659
650
    Free = limit;
667
658
      *ptr++ = SHARP_F;
668
659
    }
669
660
    PUSH_D_CACHE_REGION (free_closure, chunk_size);
670
 
    Registers[REGBLOCK_CLOSURE_LIMIT] = ((SCHEME_OBJECT) limit);
671
 
    Registers[REGBLOCK_CLOSURE_FREE] = ((SCHEME_OBJECT) (free_closure + 3));
 
661
    SET_CLOSURE_SPACE (limit);
 
662
    SET_CLOSURE_FREE (free_closure + 3);
672
663
  }
673
 
  return;
674
664
}
675
665
 
676
666
#endif /* IN_CMPINT_C */
688
678
#define CLEAR_LOW_BIT(word)                     ((word) & ((unsigned long) -2))
689
679
#define OFFSET_WORD_CONTINUATION_P(word)        (((word) & 1) != 0)
690
680
 
691
 
#if (PC_ZERO_BITS == 0)
692
 
/* Instructions aligned on byte boundaries */
693
 
#define BYTE_OFFSET_TO_OFFSET_WORD(offset)      ((offset) << 1)
694
 
#define OFFSET_WORD_TO_BYTE_OFFSET(offset_word)                         \
695
 
  ((CLEAR_LOW_BIT(offset_word)) >> 1)
696
 
#endif
697
 
 
698
 
#if (PC_ZERO_BITS == 1)
699
 
/* Instructions aligned on word (16 bit) boundaries */
700
 
#define BYTE_OFFSET_TO_OFFSET_WORD(offset)      (offset)
701
 
#define OFFSET_WORD_TO_BYTE_OFFSET(offset_word)                         \
702
 
  (CLEAR_LOW_BIT(offset_word))
703
 
#endif
704
 
 
705
 
#if (PC_ZERO_BITS >= 2)
706
 
/* Should be OK for =2, but bets are off for >2 because of problems
707
 
   mentioned earlier!
708
 
*/
709
 
#define SHIFT_AMOUNT                            (PC_ZERO_BITS - 1)
710
 
#define BYTE_OFFSET_TO_OFFSET_WORD(offset)      ((offset) >> (SHIFT_AMOUNT))
711
 
#define OFFSET_WORD_TO_BYTE_OFFSET(offset_word)                         \
712
 
  ((CLEAR_LOW_BIT(offset_word)) << (SHIFT_AMOUNT))
713
 
#endif
 
681
#define BYTE_OFFSET_TO_OFFSET_WORD(offset) ((offset) >> 1)
 
682
#define OFFSET_WORD_TO_BYTE_OFFSET(word) ((CLEAR_LOW_BIT (word)) << 1)
714
683
 
715
684
#define MAKE_OFFSET_WORD(entry, block, continue)                        \
716
685
  ((BYTE_OFFSET_TO_OFFSET_WORD(((char *) (entry)) -                     \
717
686
                               ((char *) (block)))) |                   \
718
687
   ((continue) ? 1 : 0))
719
688
 
720
 
#if (EXECUTE_CACHE_ENTRY_SIZE == 2)
721
689
#define EXECUTE_CACHE_COUNT_TO_ENTRIES(count)                           \
722
690
  ((count) >> 1)
723
691
#define EXECUTE_CACHE_ENTRIES_TO_COUNT(entries)                         \
724
692
  ((entries) << 1)
725
 
#endif
726
 
 
727
 
#if (EXECUTE_CACHE_ENTRY_SIZE == 4)
728
 
#define EXECUTE_CACHE_COUNT_TO_ENTRIES(count)                           \
729
 
  ((count) >> 2)
730
 
#define EXECUTE_CACHE_ENTRIES_TO_COUNT(entries)                         \
731
 
  ((entries) << 2)
732
 
#endif
733
 
 
734
 
#if (!defined(EXECUTE_CACHE_COUNT_TO_ENTRIES))
735
 
#define EXECUTE_CACHE_COUNT_TO_ENTRIES(count)                           \
736
 
  ((count) / EXECUTE_CACHE_ENTRY_SIZE)
737
 
#define EXECUTE_CACHE_ENTRIES_TO_COUNT(entries)                         \
738
 
  ((entries) * EXECUTE_CACHE_ENTRY_SIZE)
739
 
#endif
740
693
 
741
694
/* The first entry in a cc block is preceeded by 2 headers (block and nmv),
742
695
   a format word and a gc offset word.   See the early part of the
789
742
#define COMPILED_ENTRY_MAXIMUM_ARITY    COMPILED_ENTRY_FORMAT_LOW
790
743
#define COMPILED_ENTRY_MINIMUM_ARITY    COMPILED_ENTRY_FORMAT_HIGH
791
744
 
792
 
#endif /* CMPINTMD_H_INCLUDED */
 
745
#endif /* !SCM_CMPINTMD_H_INCLUDED */