Esempio n. 1
0
void CS_DelCodeAfter (CodeSeg* S, unsigned Last)
/* Delete all entries including the given one */
{
    /* Get the number of entries in this segment */
    unsigned Count = CS_GetEntryCount (S);

    /* First pass: Delete all references to labels. If the reference count
     * for a label drops to zero, delete it.
     */
    unsigned C = Count;
    while (Last < C--) {

       	/* Get the next entry */
       	CodeEntry* E = CS_GetEntry (S, C);

       	/* Check if this entry has a label reference */
       	if (E->JumpTo) {
       	    /* If the label is a label in the label pool and this is the last
       	     * reference to the label, remove the label from the pool.
       	     */
       	    CodeLabel* L = E->JumpTo;
       	    int Index = CollIndex (&S->Labels, L);
       	    if (Index >= 0 && CollCount (&L->JumpFrom) == 1) {
       	     	/* Delete it from the pool */
       	     	CollDelete (&S->Labels, Index);
       	    }

	    /* Remove the reference to the label */
	    CS_RemoveLabelRef (S, E);
	}

    }

    /* Second pass: Delete the instructions. If a label attached to an
     * instruction still has references, it must be references from outside
     * the deleted area. Don't delete the label in this case, just make it
     * ownerless and move it to the label pool.
     */
    C = Count;
    while (Last < C--) {

    	/* Get the next entry */
    	CodeEntry* E = CS_GetEntry (S, C);

    	/* Check if this entry has a label attached */
    	if (CE_HasLabel (E)) {
	    /* Move the labels to the pool and clear the owner pointer */
	    CS_MoveLabelsToPool (S, E);
	}

	/* Delete the pointer to the entry */
	CollDelete (&S->Entries, C);

	/* Delete the entry itself */
	FreeCodeEntry (E);
    }
}
Esempio n. 2
0
static unsigned GetRegInfo1 (CodeSeg* S,
                             CodeEntry* E,
                             int Index,
                             Collection* Visited,
                             unsigned Used,
                             unsigned Unused,
                             unsigned Wanted)
/* Recursively called subfunction for GetRegInfo. */
{
    /* Remember the current count of the line collection */
    unsigned Count = CollCount (Visited);

    /* Call the worker routine */
    unsigned R = GetRegInfo2 (S, E, Index, Visited, Used, Unused, Wanted);

    /* Restore the old count, unmarking all new entries */
    unsigned NewCount = CollCount (Visited);
    while (NewCount-- > Count) {
        CodeEntry* E = CollAt (Visited, NewCount);
        CE_ResetMark (E);
        CollDelete (Visited, NewCount);
    }

    /* Return the registers used */
    return R;
}
Esempio n. 3
0
void PopSearchPath (SearchPaths* P)
/* Remove a search path from the head of an existing search path list */
{
    /* Remove the path at position 0 */
    xfree (CollAt (P, 0));
    CollDelete (P, 0);
}
Esempio n. 4
0
static void CloseIncludeFile (void)
/* Close an include file and switch to the higher level file. Set Input to
 * NULL if this was the main file.
 */
{
    AFile* Input;

    /* Get the number of active input files */
    unsigned AFileCount = CollCount (&AFiles);

    /* Must have an input file when called */
    PRECONDITION (AFileCount > 0);

    /* Get the current active input file */
    Input = (AFile*) CollLast (&AFiles);

    /* Close the current input file (we're just reading so no error check) */
    fclose (Input->F);

    /* Delete the last active file from the active file collection */
    CollDelete (&AFiles, AFileCount-1);

    /* If we had added an extra search path for this AFile, remove it */
    if (Input->SearchPath) {
        PopSearchPath (UsrIncSearchPath);
    }

    /* Delete the active file structure */
    FreeAFile (Input);
}
Esempio n. 5
0
static void ExecCmd (Collection* Args, const CmdEntry* Tab, unsigned Count)
/* Search for the command in slot 0 of the given collection. If found, check
 * the argument count, then execute it. If there are problems, output a
 * diagnostic.
 */
{
    /* Search for the command, check number of args, then execute it */
    const char* Cmd = CollAt (Args, 0);
    const CmdEntry* E = FindCmd (Cmd, Tab, Count);
    if (E == 0) {
        PrintLine ("No such command: %s", Cmd);
        return;
    }

    /* Check the number of arguments. Zero means that the function will check
     * itself. A negative count means that the function needs at least
     * abs(count) arguments. A positive count means that the function needs
     * exactly this number of arguments.
     * Note: The number includes the command itself.
     */
    if (E->ArgCount > 0 && (int)CollCount (Args) != E->ArgCount) {
        /* Argument number mismatch */
        switch (E->ArgCount) {

            case 1:
                PrintLine ("Command doesn't accept an argument");
                return;

            case 2:
                PrintLine ("Command requires an argument");
                return;

            default:
                PrintLine ("Command requires %d arguments", E->ArgCount-1);
                return;
        }
    } else if (E->ArgCount < 0 && (int)CollCount (Args) < -E->ArgCount) {
        /* Argument number mismatch */
        switch (E->ArgCount) {

            case -2:
                PrintLine ("Command requires at least one argument");
                return;

            default:
                PrintLine ("Command requires at least %d arguments", E->ArgCount-1);
                return;
        }
    } else {
        /* Remove the command from the argument list, then execute it */
        CollDelete (Args, 0);
        E->Func (Args);
    }
}
Esempio n. 6
0
void CS_DelEntry (CodeSeg* S, unsigned Index)
/* Delete an entry from the code segment. This includes moving any associated
 * labels, removing references to labels and even removing the referenced labels
 * if the reference count drops to zero.
 * Note: Labels are moved forward if possible, that is, they are moved to the
 * next insn (not the preceeding one).
 */
{
    /* Get the code entry for the given index */
    CodeEntry* E = CS_GetEntry (S, Index);

    /* If the entry has a labels, we have to move this label to the next insn.
     * If there is no next insn, move the label into the code segement label
     * pool. The operation is further complicated by the fact that the next
     * insn may already have a label. In that case change all reference to
     * this label and delete the label instead of moving it.
     */
    unsigned Count = CE_GetLabelCount (E);
    if (Count > 0) {

     	/* The instruction has labels attached. Check if there is a next
     	 * instruction.
     	 */
     	if (Index == CS_GetEntryCount (S)-1) {

     	    /* No next instruction, move to the codeseg label pool */
     	    CS_MoveLabelsToPool (S, E);

     	} else {

     	    /* There is a next insn, get it */
     	    CodeEntry* N = CS_GetEntry (S, Index+1);

     	    /* Move labels to the next entry */
     	    CS_MoveLabels (S, E, N);

     	}
    }

    /* If this insn references a label, remove the reference. And, if the
     * the reference count for this label drops to zero, remove this label.
     */
    if (E->JumpTo) {
       	/* Remove the reference */
       	CS_RemoveLabelRef (S, E);
    }

    /* Delete the pointer to the insn */
    CollDelete (&S->Entries, Index);

    /* Delete the instruction itself */
    FreeCodeEntry (E);
}
Esempio n. 7
0
void CollMove (Collection* C, unsigned OldIndex, unsigned NewIndex)
/* Move an item from one position in the collection to another. OldIndex
** is the current position of the item, NewIndex is the new index after
** the function has done it's work. Existing entries with indices NewIndex
** and up are moved one position upwards.
*/
{
    /* Get the item and remove it from the collection */
    void* Item = CollAt (C, OldIndex);
    CollDelete (C, OldIndex);

    /* Correct NewIndex if needed */
    if (NewIndex >= OldIndex) {
        /* Position has changed with removal */
        --NewIndex;
    }

    /* Now insert it at the new position */
    CollInsert (C, Item, NewIndex);
}
Esempio n. 8
0
File: objdata.c Progetto: cc65/cc65
void DelObjData (const char* Module)
/* Delete the object module from the list */
{
    unsigned I;
    for (I = 0; I < CollCount (&ObjPool); ++I) {

        /* Get this object file */
        ObjData* O = CollAtUnchecked (&ObjPool, I);

        /* Did we find it? */
        if (strcmp (O->Name, Module) == 0) {

            /* Free the entry */
            CollDelete (&ObjPool, I);
            FreeObjData (O);

            /* Done */
            return;
        }
    }

    /* Not found! */
    Warning ("Module '%s' not found in library '%s'", Module, LibName);
}
Esempio n. 9
0
void CS_DelCodeRange (CodeSeg* S, unsigned First, unsigned Last)
/* Delete all entries between first and last, both inclusive. The function
 * can only handle basic blocks (First is the only entry, Last the only exit)
 * and no open labels. It will call FAIL if any of these preconditions are
 * violated.
 */
{
    unsigned   I;
    CodeEntry* FirstEntry;

    /* Do some sanity checks */
    CHECK (First <= Last && Last < CS_GetEntryCount (S));

    /* If Last is actually the last insn, call CS_DelCodeAfter instead, which
     * is more flexible in this case.
     */
    if (Last == CS_GetEntryCount (S) - 1) {
        CS_DelCodeAfter (S, First);
        return;
    }

    /* Get the first entry and check if it has any labels. If it has, move
     * them to the insn following Last. If Last is the last insn of the code
     * segment, make them ownerless and move them to the label pool.
     */
    FirstEntry = CS_GetEntry (S, First);
    if (CE_HasLabel (FirstEntry)) {
        /* Get the entry following last */
        CodeEntry* FollowingEntry = CS_GetNextEntry (S, Last);
        if (FollowingEntry) {
            /* There is an entry after Last - move the labels */
            CS_MoveLabels (S, FirstEntry, FollowingEntry);
        } else {
     	    /* Move the labels to the pool and clear the owner pointer */
     	    CS_MoveLabelsToPool (S, FirstEntry);
        }
    }

    /* First pass: Delete all references to labels. If the reference count
     * for a label drops to zero, delete it.
     */
    for (I = Last; I >= First; --I) {

       	/* Get the next entry */
       	CodeEntry* E = CS_GetEntry (S, I);

       	/* Check if this entry has a label reference */
       	if (E->JumpTo) {

       	    /* If the label is a label in the label pool, this is an error */
       	    CodeLabel* L = E->JumpTo;
       	    CHECK (CollIndex (&S->Labels, L) < 0);

 	    /* Remove the reference to the label */
 	    CS_RemoveLabelRef (S, E);
 	}
    }

    /* Second pass: Delete the instructions. If a label attached to an
     * instruction still has references, it must be references from outside
     * the deleted area, which is an error.
     */
    for (I = Last; I >= First; --I) {

    	/* Get the next entry */
    	CodeEntry* E = CS_GetEntry (S, I);

       	/* Check if this entry has a label attached */
    	CHECK (!CE_HasLabel (E));

	/* Delete the pointer to the entry */
	CollDelete (&S->Entries, I);

	/* Delete the entry itself */
	FreeCodeEntry (E);
    }
}