Abstract:
A computer instruction includes a declaration instruction that results in a variable name being associated with a memory location in one of a plurality of memories, the declaration instruction having a first field to specify the variable name, a second field to specify a one of the plurality of memory systems to associate with the variable name.

Description:
TECHNICAL FIELD  
         [0001]    This application relates to compilation techniques and instructions for programming.  
         BACKGROUND  
         [0002]    Parallel processing is an efficient form of information processing of concurrent events in a computing process. In the context of a parallel processor, parallelism involves doing more than one thing at the same time. Unlike a serial paradigm where all tasks are performed sequentially at a single station or a pipelined machine where tasks are performed at specialized stations, with parallel processing, many stations are provided, each capable of performing various tasks simultaneously. A number of stations work simultaneously and independently on the same or common elements of a computing task. Accordingly, using or applying parallel processing can solve computing tasks.  
           [0003]    A compiler program is generally used to convert a source code file written in a high-level programming language (e.g., COBOL, C, C++, etc.) into an executable program, i.e., a corresponding set of machine language instructions that are executable by a computer processor. The compiler typically performs a multi-step process that begins with converting each high-level source code file into a corresponding assembly language file followed by converting each assembly language files into a corresponding machine language file. A link editor (a “linker”) is then used to combine each of the machine language files into a single executable program. The format of the machine language instructions included in the executable program are specific to the architecture of the computer processor that will be used to execute the program. 
       
    
    
     DESCRIPTION OF THE DRAWINGS  
       [0004]    [0004]FIG. 1 is a block diagram of a processing system having multiple memories.  
         [0005]    [0005]FIG. 2 is a flowchart showing a compilation process.  
         [0006]    [0006]FIG. 3 is a more detailed block diagram of a portion of the processing system of FIG. 1.  
         [0007]    [0007]FIG. 4 is a block diagram of computer hardware for execution of the compilation process of FIG. 2. 
     
    
     DESCRIPTION  
       [0008]    Referring to FIG. 1, processing system  100  includes a parallel, hardware-based multithreaded processor module  112  that includes a processor core  120 . Processor core  120  performs general purpose computer type functions such as handling protocols, exceptions, and providing extra support for packet processing where the programmable micro-engines  116   a - 116   f  process the packets and, in some cases, pass the packets off to processor core  120  (e.g.) for more detailed processing such as in boundary conditions.  
         [0009]    A programmable micro-engines  116   a - 116   f  includes a control store  130   a - 130   f , respectively, which in this example are implemented as random access memories (RAMs) of  4096  instructions, each of which is 40-bits wide. Control stores  130   a - 130   f  are used to store an executable program, or a portion of an executable program, compiled by process  200 . The executable programs are loadable into control stores  130   a - 130   f  by processor core  120 .  
         [0010]    The programming engines  116   a - 116   f  each maintain program counters in hardware and states associated with the program counters. Effectively, corresponding sets of context or threads can be simultaneously active on each of the programming engines  116   a - 116   f  while only one is actually executing at any one time.  
         [0011]    Memory sub-system  113  includes a SCRATCH random access memory  113   a  (SCRATCH RAM  113 ) and a memory controller  113   b , both of which are included on processor module  112 . Memory sub-system  114  includes a static random access memory  114   a  (SRAM  114   a ), and a corresponding SRAM controller  114   b . Memory sub-system  115  includes a synchronous dynamic random access memory  115   a  (SDRAM  115   a ) and a corresponding SDRAM controller  115   b . In this example, SRAM controller  114   b  and SDRAM controller  115   b  are both located on processor module  112 , while their corresponding memories SRAM  114   a  and SDRAM  115   a  are not. All of the memory controllers  113   b - 115   b  are connected by command/address bus  117  and data bus  118  to micro-engines  116   a - 116   f  and a core processor  120 . The memory sub-systems operate asynchronously, receiving memory access requests (e.g., reads, writes and swaps) from the micro-engines and the core processor.  
         [0012]    SDRAM memory  115   a  and SDRAM controller  115   b  are typically used for storing and processing large volumes of data, respectively. For example, storing and processing of network payloads from network packets. SRAM memory  114   a  and SRAM controller  114   b  are typically used in a networking implementation for low latency, fast access tasks, e.g., accessing look-up tables, memory for the core processor  120 , and the like. Referring to FIG. 2, a compilation process  200  is used to compile an executable program  214  from source code files  206   a - 206   c  that include extended high-level language (XHLL) instructions. Executable program  214  may be executed by programmable micro-engines  116   a - 116   f  included in the parallel processing system  100  (FIG. 1). In this example of processing system  100 , the command/address bus  117  and data bus  118  connect micro-engines  116   a - 116   f  and three memory sub-systems  113 - 115 . Each of the memory sub-systems  113 - 115  operates asynchronously and has different access speeds and may also have different read and write data sizes.  
         [0013]    Each of the programmable micro-engines  116   a - 116   f  supports parallel execution of multiple contexts or threads. Multi-threaded execution allows a thread to perform computations while another thread waits for an input-output (I/O) operation to complete, typically, a memory access to one of the memory sub-systems, or for a signal from another hardware unit to be received. If only single-threaded execution was supported, the programmable micro-engines would sit idle for a significant number of cycles waiting for memory references to complete or signals to be received reducing overall computational throughput of system  100 . In an embodiment, XHLL instructions are implemented in a “C” language format (a syntax) and include a set of memory specifiers and context synchronization specifiers. The set of memory specifiers includes specifiers corresponding to each of the memory sub-systems  113 - 115 , and are used to specify an access type operation (i.e., a read or write) to be performed by a specific memory sub-system. The set of context synchronization specifiers are used to indicate under what conditions an executing thread may be swapped in or out of execution by micro-engine, as will be explained. The use of XHLL instructions that include memory and context synchronization specifiers, may provide a programmer the ability to control specific hardware and/or context scheduling features of processing system  100 . Furthermore, the use of XHLL instructions to program processing system  100  may enable a programmer to efficiently schedule multi-threaded execution by a micro-engine, e.g., where an executing thread may need to wait for a requested memory access to complete. The use of XHLL instructions to program processing system  100  also may reduce program development time since the need for specialized knowledge of the processor architecture is not required. That is, a programmer may be able to program the operation of specific hardware included in processing system  100  using high-level language instructions rather than using relatively more difficult assembly-level language instructions.  
         [0014]    Referring to FIG. 3, an exemplary micro-engine  116   a  and an exemplary memory controller, e.g., SDRAM controller  115   b  are shown in greater detail. The other micro-engines ( 116   b - 116   f ) are constructed similarly. The other memory controllers ( 113   b - 114   b ) may be constructed in a similar fashion. Micro-engine  116   a  includes a set of 128 transfer registers  150   a  (hereafter referred to as “XFR&#39;s”), divided logically into four sets of  32 ×FRs  151   a - 154   a . Each of the four sets of XFRs are used for reading or writing data to a specific memory sub-system. In more detail, XFR set  151   a  is used for data reads from SDRAM  115   a , XFR set  152   a  is used for data writes to SDRAM  115   a , XFR set  153   a  is used for data reads from SRAM  114   a  and XFR set  154   a  is used for data writes to SRAM  114   a.    
         [0015]    Exemplary memory controller  115   b  includes queuing logic  155  that is used to store and select among memory access commands received from the micro-engines  116   a - 116   f  and/or core processor  120 . Each of the memory access commands sent to a memory controller includes an address field to specify an address location in a memory, a command field to specify the type of access (i.e, a read or write) and may also include an access size (e.g., a byte, word, long-word, etc.) In this example, queueing logic  155  includes a command queue  160  to store memory access commands received on command/address bus  117 , and a selection logic block  170  connected to control an output from MUX  162  to select a stored memory access instructions from command queue  160 . The output from MUX  162  includes the address field from the selected memory access instruction, which is input to a pin interface block  180  along with the corresponding data on bus  118 . In an embodiment, the set of XHLL instructions includes a queueing priority specifier that when compiled and executed by a micro-engine causes a memory access instruction to be sent to a memory controller that includes a field corresponding to the queueing priority specifier. In this example, the queuing priority specifier field included in a memory access instruction sent to memory controller  115   b , is used by selection logic block  170  to determine the selection of a stored memory access command from command queue  160 .  
         [0016]    Processing system  100  is especially useful for tasks that can be broken into parallel subtasks or functions. In this example, each of the six programmable micro-engines  116   a - 116   f  may execute up to four (4) threads. Executable programs compiled by process  200  are executed in each of programmable micro-engines  116   a - 116   f  and may cause memory accesses to DRAM  115   a , SRAM  114   a  or SCRATCH RAM  113   a . Programs written with XHLL instructions allow a programmer to select which of the memory sub-systems  113 - 115  to access based on characteristics of the data. Typically, low latency, low bandwidth data is stored in and fetched from SRAM memory  114   a  or SCRATCH RAM  113   a , whereas higher bandwidth data for which latency is not as important, is stored in and fetched from SDRAM memory  115   a.    
         [0017]    Exemplary micro-engine  116   c  includes a register set  140  that includes a program counter (PC), and context specific local registers to allow for context swapping of the multiple contexts on each micro-engine. The other micro-engines,  116   b - 116   f  are constructed similarly. These registers sets are used to store context specific information and eliminates the need to move some of that information between a memory sub-system and the register set for each context swap performed by a micro-engine.  
         [0018]    In this example of processing system  100 , processor core  120  is an XScale™ based architecture. The processor core  120  has an operating system (not shown). Through the operating system (OS), the processor core  120  can call functions to operate on the programmable micro-engines  116   a - 116   f . The processor core  120  can use any supported OS, in particular, a real time OS. For the core processor  20  implemented as an XScale™ architecture, operating systems such as Microsoft NT real-time, VXWorks and μCOS, or a freeware OS available over the Internet can be used.  
         [0019]    Each of the memory sub-systems  113 - 115  has a separate address space. Also, in this example of processing system  100 , SCRATCH RAM  113   a  and SRAM  114   a  are addressable by longwords (32 bits) and SDRAM  115   a  is addressable by quadwords (64 bits). As stated previously, accesses to memory sub-systems  113 - 115  are completed asynchronously. Therefore, when a memory location in one of the memory sub-systems is accessed by a program executing in a micro-engine, the thread must either be swapped out (by executing a context swap instruction), allowing other threads to run, or must wait until the operation is signaled as complete before using the data being read. Similarly, when a data value is being written to a memory sub-system by a first instruction, that data value may not be read by a second instruction before the write to that memory has completed.  
         [0020]    The use of XHLL instructions that include a context synchronization specifier allows a programmer to specify a condition (or signal) to cause a context swap to occur. For example, two threads may access a shared memory sub-system, e.g., one of memory sub-systems  113 - 115 . Each of the memory controllers  113   b - 115   b  sends a completion signal when a requested memory access received from one of the programmable micro-engine threads has completed and the requested memory data has been read or written. When the programmable micro-engines  116   a - 116   f  receives the completion signal, the programmable micro-engines  116   a - 116   f  can determine which thread to execute based on a context synchronization specifier that specifies that condition, i.e., receipt of the completion signal.  
         [0021]    One example of an application for the hardware-based multithreaded processor  112  is as a network processor. As a network processor, the hardware-based multithreaded processor  112  interfaces to network devices such as a Media Access Controller (MAC) device (not shown) or a Gigabit Ethernet device (not shown). In general, as a network processor, the hardware-based multithreaded processor  112  can interface to any type of communication device or interface that receives or sends large amounts of data. Processing system  100  functioning in a networking application can receive network packets and process those packets in a parallel manner.  
         [0022]    XHLL Instructions  
         [0023]    In an embodiment, XHLL instructions include a set of memory specifiers that allow a programmer to specify an action related to a specific memory sub-system  113 - 115 . As an example, and as shown below in Examples 1-4, XHLL instructions include “declspec( )” instructions that allow a programmer to declare a variable (or pointer) along with a memory specifier that specifies a memory sub-system where the data value for that variable will be stored. When the declspec( ) instruction is compiled by process  200  and executed by one of the micro-engines  116   a - 116   f, a  variable corresponding to the variable in the declspec( ) instruction will be stored in a location within the specified memory sub-system  113 - 115 . In each of Examples 1-4 (below) one or more memory specifiers are included in the instructions (located within the “( )” portion of each instruction) that specify the memory sub-system (i.e., a memory region) for storing the corresponding data and/or a pointer:  
       EXAMPLE 1  
       [0024]    declspec(SCRATCH) var1  
         [0025]    declspec (SRAM) var2  
         [0026]    declspec (SDRAM) var3  
         [0027]    Example 1 includes: a declaration of a first variable “var1” that will be stored in SCRATCH RAM  113   a ; a declaration of a second variable “var2” that will be stored in SRAM  114   a ; and a declaration of a third variable “var3” that will be stored in SDRAM  115   a.    
       EXAMPLE 2  
       [0028]    declspec(SRAM) struct msg_header header;  
         [0029]    Example 2 includes a declaration of a data structure with a variable of type “msg_header” which will be stored in SRAM  114   a . Example 2 is an instruction that declares a variable named “header” of type “msg_header” stored in SRAM. also includes a pointer, “header”, that will also be stored in SRAM and may be used to point to the data structure “msg_header”.  
       EXAMPLE 3  
       [0030]    declspec(SDRAM) buffer * buf_ptr;  
         [0031]    Example 3 includes a declaration of a data buffer, “buffer”, that will be stored in SDRAM  115   a  and includes a pointer to the data buffer called “buf_ptr”. Please note that in Example 3, since “buf_ptr” is not specifically assigned to a memory sub-system, “buf_ptr” will be assigned by default to a general purpose register of the executing micro-engine.  
       EXAMPLE 4  
       [0032]    buffer declspec(SDRAM)*declspec(SCRATCH) buf_ptr — 1;  
         [0033]    Example 4 includes a declaration of a pointer “buf_ptr_ 1 ” that will be stored in a SCRATCH RAM  113   a  location. “Buf_ptr — 1” will point to a data buffer “buffer” that will be stored in SDRAM  115   a.    
         [0034]    The declspec( ) instructions have the memory specifier included within the parentheses “( )” and it applies to the variable declaration preceding the memory specifier. That is, the first memory specifier in Example 4 indicates that the data buffer is to be stored in SDRAM  115   a , while the second memory specifier indicates the pointer is to be stored in SCRATCH RAM  113   a.    
         [0035]    Shared Data  
         [0036]    XHLL instructions include a shared specifier used to declare and/or use a shared variable stored in one of the memory sub-systems  113   b - 115   b  or a register. In this way, a first thread executing on a micro-engine may declare a shared variable that is stored in one of the memory sub-systems  113 - 115  or stored in a micro-engine register that is accessible by other threads executing on that micro-engine. This reduces the need to re-load variables when a thread is swapped in for execution by a micro-engine. As shown in Examples 5-7 (below), XHLL instructions include a shared specifier used to declare and/or use a shared variable.  
       EXAMPLE 5  
       [0037]    declspec(shared) var5  
         [0038]    Example 5 declares a shared variable “var5”. The shared data specifier may also be combined with a memory region specifier in a single declspec( ) instruction, as shown below in Example 6.  
       EXAMPLE 6  
       [0039]    declspec(shared SRAM) int x;  
         [0040]    Example 7 (below) includes a declspec( ) instruction that does not specify a memory region, therefore, a register on a micro-engine (if available) is used to store the declared variable.  
       EXAMPLE 7  
       [0041]    declspec(shared) int x; uses a register, if available  
         [0042]    Variables are usable by all threads when a shared specifier is used to declare them, alternatively, each varaiable required by a thread will be replicated.  
         [0043]    Global Data  
         [0044]    In some cases it is useful for a programmer to declare data that is “global”, i.e., shared between all of the micro-engines  116   a - 116   f  in processor  112 . In an embodiment, XHLL instructions include “export” and/or “import” specifiers that are used to declare a global export variable in a first instruction that may be imported by a second instruction. During the performance of compiler process  200 , any “export” and “import” specifiers included in source code file instructions are linked during back end sub-process ( 12 ), i.e., the imported symbols are determined from another exported symbol. Examples 8-9 (below) show the use of “export” and “import” specifiers.  
       EXAMPLE 8  
       [0045]    declspec(export) var7  
       Example 9  
       [0046]    declspec(import) var7  
         [0047]    Example 8 shows an exported/global variable “var7” that is imported by a second instruction in Example 9.  
         [0048]    Exported and imported variables may also be bound to a memory region, as shown in Example 10 (below).  
       EXAMPLE 10  
       [0049]    declspec(SDRAM import) long long buffer[BUFFER_SIZE];  
         [0050]    During the performance of process  200 , XHLL variables that are declared without a memory region specifier are allocated as follows: Variables up to 32 bytes in size are allocated to a register, if available. If there are not enough registers to accommodate a variable declaration, the variable is stored in a location in SRAM  114   a . Variables larger than 32 bytes will be stored in an SRAM location. Pointers declared without a memory specifier will point to an SRAM location.  
         [0051]    Transfer Register Specifiers  
         [0052]    As described previously, each of the micro-engines  116   a - 116   f  includes four sets of XFRs for reading and writing data to/from SRAM  114   b  and SDRAM  113   b . The XHLL instructions include transfer register specifiers used to specify one of the set of XFRs associated with a memory sub-system  113   b - 115   b . In this case, transfer register specifiers include: “sram_read_reg” (to specify a read of an XFR associated with SRAM), sram_write_reg” (to specify a write to an XFR associated with SRAM), “dram_read_reg” (to specify a read from an XFR associated with SDRAM), and “dram_write_reg” (to specify a write to a XFR associated with SDRAM). The use of transfer register specifiers allows a programmer to efficiently program system  100  that include asynchronous memories. By way of example, a first instruction in a thread specifies a variable to be read or written through a specific transfer register, which when executed by a micro-engine will cause a memory access to a specific memory sub-system. The thread may include additional instructions, which perform other operations, followed by execution of another instruction that waits for the data declared to the specific transfer register to be completed (or alternatively, checks for a completion signal). Example 11 (below) shows an example of an XHLL instruction that includes a transfer register specifier.  
       EXAMPLE 11  
       [0053]    declspec(sram_read_reg) buffer[4];  
         [0054]    Example 11 includes a first instruction that declares a four (4) word “buffer” in SRAM read XFR  151 .  
         [0055]    Context Synchronization Specifiers  
         [0056]    The XHLL instructions include a set of context synchronization specifiers (see Table 1) that are used by a micro-engine to determine the appropriate scheduling of individual threads, e.g., when a thread is waiting for the completion of a memory access or a signal from another hardware.  
                           TABLE 1                                   SPECIFIER   DESCRIPTION                           sync_none   No synchronization specified.           no_signal   No signal requested - same as               sync_none           Sig_done   Signal when operation is               complete           Ctx_swap   Swap out until operation is               complete           voluntary_swap   Swap to another task, but do not               wait for completion to swap in                      
 
         [0057]    Queueing Priority Specifiers  
         [0058]    In an embodiment, XHLL instructions include a set of queueing priority specifiers (see Table 2) that are used to specify the handling of a memory access instruction sent to a memory sub-system.  
         [0059]    As described previously, each of the memory controllers  113   b - 115   b  may include queuing logic that stores memory access commands received from the micro-engines  116   a - 116   f  and/or core processor  120 . The queueing logic also includes selection logic to select among two or memory access instructions stored for execution by that memory controller. This selection may be based, in part, upon a queueing priority specifier included as part of an XHLL instruction.  
                           TABLE 2                                   SPECIFIER   DESCRIPTION                           queue_default   Use a default queue.           optimize_mem   Choose a queue to “optimize”               memory throughput, i.e., operations               may be performed out of order.           Any_queue   Place in any queue.           Ordered   Place in an ordered queue (for               SRAM etc). All operations in this               queue are processed in order.           order_queue   Place in an ordered queue.           Priority   Place in a priority queue.               I.e., these operations take priority               over other queues.                      
 
         [0060]    A queueing priority specifier included as part of an XHLL instruction may specify “ordered” or “out of order” selection, for example, of received memory access instructions by a memory sub-system.  
       EXAMPLE 12  
       [0061]    declspec(sram_read_reg) buffer[4];  
         [0062]    declspec(sram) int *pointer;  
         [0063]    sram_read(&amp;buffer, pointer,  4 , ordered, sig_done);  
         [0064]    Example 12 depicts the reading of four (4) words from SRAM. The four (4) words will be stored in a SRAM read transfer register declared as “buffer” from an address indicated by “pointer”. Example 12 also includes a “sram_read( )” instruction that specifies that the scheduling of the read access from SRAM should be handled by SRAM controller  114   b  in an “ordered” manner (i.e., not in an “out or order” manner). The sram_read( ) instruction of example 12 also includes a “sig_done” specifier that allows a programmer to specify, in a single instruction, the priority handling of a memory access instruction and the context swapping conditions, i.e., whether a thread should be swapped out of execution, or, will be signaled (i.e., “sig_done”) when the operation is completed.  
         [0065]    Compiler Instructions  
         [0066]    Compiler instruction “ctx( )” causes compiler process  200  to determine a context number for a context scheduled for execution, for example, context number 0-3. Based on this determination compiler process  200  may select different sequences of instructions for execution by a micro-engine. Example 14 (below) includes a compiler instruction ctx( ) followed by a set of tasks, task — 0-task — 3. Each task represents a separate set of instructions that are to be performed, depending on the current context scheduled for execution.  
       EXAMPLE 14  
       [0067]    switch(ctx( ))  
         [0068]    { 
         [0069]    case 0: perform_task — 0; break;  
         [0070]    case 1: perform_task — 1; break;  
         [0071]    case 2: perform task — 2; break;  
         [0072]    case 3: perform taks — 3; break;  
         [0073]    } 
         [0074]    Example 14 illustrates how compiler process  200 , and compiler instruction ctx( ), are used to specify the execution of multiple tasks on a multi-threaded micro-engine.  
         [0075]    Compiler Process  200   
         [0076]    Referring back to FIG. 2, during the performance of compiler process  200 , front end sub-process ( 208 ) assembles ( 208   a ) each source code file  206   a - 206   c  into an intermediate object file (assembly language file)  210   a - 210   c , respectively. One or more of the source code files  206   a - 206   c  may include XHLL instructions that include specifiers that are used to control specific hardware in processing system  100  and specifiers that are used to synchronize context swaps. After intermediate object files  210   a - 210   c  are assembled, back-end sub-process ( 212 ) converts those files into a machine executable program file  214  that is executable by a micro-engine  116   a - 116   f . Back end sub-process  212 , may optionally include: context scheduling ( 212   a ) based on the on XHLL instructions that access a memory sub-system, allocating registers ( 212   b ) for shared and global variables declared by an XHLL instruction, graphing ( 212   c ) function calls and returns to determine the placement of those calls and returns in the executable program  214 , and, pointer address calculations ( 212   d ) based on the granularity of a memory sub-system specified by an XHLL instruction.  
         [0077]    Compilation process  200  includes determining from a set of XHLL instructions when a variable will be read or written to one of the memory sub-systems during execution of a program  14 . In this case, if an instruction specifies a memory sub-system access, compilation process  200  schedules a context swap while the memory access instruction completes. The context swap may be scheduled later in a program thread if other instructions (and related computations) that follow the memory access instruction do not depend on the memory reference value. In more detail, compilation process  200  may allow multiple writes and reads to one or more of the memory sub-systems to be executed before a context is swapped where it can be determined that no data conflicts will occur in subsequent instructions.  
         [0078]    In an embodiment of compilation process  200 , the performance of process  200  is not completed until all of the separate source code files  206   a - 206   c  have been assembled into intermediate object files  210   a - 210   c . Therefore, compilation process  200  may link all intermediate modules  10   a - 10   c  together during back end sub-process ( 212 ). During the performance of back end sub-process ( 212 ), process  200  may also create ( 212   c ) a graph all function calls and create ( 212   c ) a graph of all variable declarations included in intermediate files  210   a - 210   c . The graph (i.e., a table) of function calls is used by compilation process  200  to determine where in the executable program function calls and returns should be executed, for example. The graph of variable declarations, especially shared and global declarations, is used by process  200  to determine which variables to store in registers and/or one of the other memory sub-systems, for example. This way of using the call graph and variable declaration graph is especially useful to reduce the total size of the executable program, since the control stores  130   a - 130   f  in each micro-engine  116   a - 116   f  is of a limited size. Therefore, the graph of function calls may be used to determine the placement of function calls and returns in the executable program, reducing the stacking of return addresses and reducing the amount of saving and restoring of registers between function calls.  
         [0079]    As described previously, SCRATCH RAM  113   a  and SRAM  114   a  are addressable by longwords (32 bits) and SDRAM  115   a  is addressable by quadwords (64 bits). Pointers are used to address data stored in a memory sub-system, however the pointer address calculation will vary since the address granularity of each memory sub-system is different. In an embodiment, process  200  includes pointer calculations ( 12   d ), i.e., calculating the machine address for each pointer declared based on the address granularity of each memory sub-system. For example, when incrementing a pointer for a “*long long” pointer to an SRAM  114   a  location, the pointer value is incremented by 2, whereas if incrementing the same pointer “*long long” to an SDRAM  114   a  location, the pointer value is incremented by 1. A corresponding inverse adjustment is performed for pointer difference operations. Other instructions may also be used to adjust for address granularity of the various memory sub-systems, for example shifting instructions may be used.  
         [0080]    [0080]FIG. 3 shows a computer  300  on which compilation process  200  may be implemented. Computer  300  includes a processor  310 , a memory  312 , and a storage medium  314  (see view  336 ). Storage medium  314  stores data  318  and machine-executable instructions  320  that are executed by processor  310  out of memory  312  to perform compilation process  200 .  
         [0081]    Although a personal computer is shown in FIG. 3, process  200  is not limited to use with the hardware and software of FIG. 3. It may find applicability in any computing or processing environment. Process  200  may be implemented in hardware, software, or a combination of the two. Process  200  may be implemented in computer programs executing on programmable computers or other machines that each include a processor, a storage medium readable by the processor (including volatile and non-volatile memory and/or storage components), at least one input device, and one or more output devices. Program code may be applied to data entered using an input device (e.g., a mouse or keyboard) to perform process  200  and to generate output information.  
         [0082]    Each such program may be implemented in a high level procedural or object-oriented programming language to communicate with a computer system. However, the programs can be implemented in assembly or machine language. The language may be a compiled or an interpreted language.  
         [0083]    Each computer program may be stored on a storage medium/article (e.g., CD-ROM, hard disk, or magnetic diskette) that is readable by a general or special purpose programmable computer for configuring and operating the computer when the storage medium or device is read by the computer to perform process  200 . Process  200  may also be implemented as a machine-readable storage medium, configured with a computer program, where, upon execution, instructions in the computer program cause a machine to operate in accordance with process  200 . The invention is not limited to the specific embodiments described above. For example, more or fewer of memory sub-systems  113 - 115  may be included on the board (or integrated circuit) of processor  112 .  
         [0084]    Other embodiments not described herein are also within the scope of the following claims.