exspiminator-commits Mailing List for The Exspiminator
Status: Alpha
Brought to you by:
nphillips
You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(26) |
Oct
(43) |
Nov
(65) |
Dec
|
|---|
|
From: Nigel P. <nph...@us...> - 2001-11-26 14:12:44
|
Update of /cvsroot/exspiminator/exspiminator/docs In directory usw-pr-cvs1:/tmp/cvs-serv23735/docs Modified Files: release.html Log Message: Indicate directives documentation. Index: release.html =================================================================== RCS file: /cvsroot/exspiminator/exspiminator/docs/release.html,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -r1.22 -r1.23 *** release.html 2001/11/22 12:02:07 1.22 --- release.html 2001/11/26 14:12:42 1.23 *************** *** 22,26 **** <li>Rewrote old two-pass assembler as a single pass assembler <li>Tightened up type checking ! <li>Added some assembler directives. </ul> --- 22,26 ---- <li>Rewrote old two-pass assembler as a single pass assembler <li>Tightened up type checking ! <li>Added some assembler directives (see tutorial). </ul> |
|
From: Nigel P. <nph...@us...> - 2001-11-26 14:12:01
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv23472/base
Modified Files:
NewAssembler.java Line.java
Log Message:
Fixed and tested duplicate label on backpatched lines bug.
Index: NewAssembler.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/NewAssembler.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** NewAssembler.java 2001/11/23 10:50:14 1.6
--- NewAssembler.java 2001/11/26 14:11:58 1.7
***************
*** 225,228 ****
--- 225,230 ----
if (incompletes!=null)
{
+ // remove label so we don't process it twice and get duplicate label error
+ line.stripLabel();
incompletes.add(new AssemblyLine(line, lineNum, currentAddress));
}
Index: Line.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/Line.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** Line.java 2001/11/22 17:39:16 1.3
--- Line.java 2001/11/26 14:11:58 1.4
***************
*** 41,44 ****
--- 41,52 ----
}
+ /** Sets the label component to null and returns this line. Note this interface requires the
+ mutability of this class.*/
+ public Line stripLabel()
+ {
+ label=null;
+ return this;
+ }
+
/** For debugging.*/
public String toString()
|
|
From: Nigel P. <nph...@us...> - 2001-11-26 14:12:01
|
Update of /cvsroot/exspiminator/exspiminator/samples In directory usw-pr-cvs1:/tmp/cvs-serv23472/samples Modified Files: triv.txt Log Message: Fixed and tested duplicate label on backpatched lines bug. Index: triv.txt =================================================================== RCS file: /cvsroot/exspiminator/exspiminator/samples/triv.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** triv.txt 2001/11/22 17:39:16 1.11 --- triv.txt 2001/11/26 14:11:58 1.12 *************** *** 8,10 **** addi 5, 5, 2 f: mr 4, 4# ! g: xori 6, 7, 8 \ No newline at end of file --- 8,12 ---- addi 5, 5, 2 f: mr 4, 4# ! g: xori 6, 7, 8 ! label1: beq label2 ! label2: blr \ No newline at end of file |
|
From: Nigel P. <nph...@us...> - 2001-11-23 10:50:17
|
Update of /cvsroot/exspiminator/exspiminator/gui
In directory usw-pr-cvs1:/tmp/cvs-serv24016/gui
Modified Files:
GUI.java
Log Message:
Switch from InstructionEncoders to assembler subclasses.
Index: GUI.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/gui/GUI.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -C2 -r1.24 -r1.25
*** GUI.java 2001/11/22 11:59:10 1.24
--- GUI.java 2001/11/23 10:50:14 1.25
***************
*** 400,410 ****
in.read(source, 0, (int) fileLength);
! NewAssembler asm=new NewAssembler(
! SimplifiedPowerPCInstructionSet.getInstructionSet());
! //System.err.println(pp.getLabelTable().toString());
try
{
byte[] code=asm.assemble(new String(source));
- //(new String(data), pp.getLabelTable());
if (asm.hasWarnings())
{
--- 400,407 ----
in.read(source, 0, (int) fileLength);
! NewAssembler asm=new PowerPCAssembler();
try
{
byte[] code=asm.assemble(new String(source));
if (asm.hasWarnings())
{
|
|
From: Nigel P. <nph...@us...> - 2001-11-23 10:50:17
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv24016/base
Modified Files:
NewAssembler.java
Added Files:
PowerPCAssembler.java
Removed Files:
InstructionEncoder.java PowerPCInstructionEncoder.java
Log Message:
Switch from InstructionEncoders to assembler subclasses.
--- NEW FILE ---
package exspiminator.base;
/** An assembler for the PowerPC instruction set.
BUG: allow the prefixes and force values to be set by the user!
*/
public class PowerPCAssembler extends NewAssembler
{
String gprPrefix;
String crfPrefix;
String crbPrefix;
int forceGprPrefix;
int forceCrfPrefix;
int forceCrbPrefix;
public PowerPCAssembler()
{
this(true);
}
public PowerPCAssembler(boolean allowSimplifiedMnemonics)
{
super(allowSimplifiedMnemonics
? SimplifiedPowerPCInstructionSet.getInstructionSet()
: PowerPCInstructionSet.getInstructionSet());
gprPrefix="r";
forceGprPrefix=WARN;
crfPrefix="cr";
forceCrfPrefix=WARN;
crbPrefix="crb";
forceCrbPrefix=WARN;
}
int parseGpr(String s) throws OperandFormatException
{
int result;
if (s.startsWith(gprPrefix))
{
result=parseInt(s.substring(gprPrefix.length()));
}
else
{
warn(forceGprPrefix, "Missing GPR prefix");
result=parseInt(s);
}
if (result<0 || result>31)
{
warn(ERROR, "GPR index out of bounds");
}
return result;
}
/** A wrapper around parseGpr which does not require the gprPrefix to be used when the value is zero, and
warns if it is present.*/
int parseA0(String s) throws OperandFormatException
{
int result;
try
{
result=Integer.parseInt(s);
if (result==0)
{
return result;
}
}
catch (NumberFormatException ex)
{
// fall through
}
int prefixed=parseGpr(s);
if (prefixed==0)
{
warn(WARN, "Register 0 specified where literal 0 will be coded");
}
return prefixed;
}
/** A wrapper around parseGpr which produces an error then the value is zero.*/
int parseANOT0(String s) throws OperandFormatException
{
int result=parseGpr(s);
if (result==0)
{
warn(ERROR, "Register 0 is invalid as a base register in the instruction");
}
return result;
}
int parseCrb(String s) throws OperandFormatException
{
int result;
if (s.startsWith(crbPrefix))
{
result=parseInt(s.substring(crbPrefix.length()));
}
else
{
warn(forceCrbPrefix, "Missing CRB prefix (" + crbPrefix + ")");
result=parseInt(s);
}
if (result<0 || result>31)
{
warn(ERROR, "CRB index out of bounds");
}
return result;
}
/** Could be optimized by insertXXX equivalents of PowerPCUtils.extractXXX stuff.
Could be generalized?*/
public int insertField(int opcode, int fieldID, String rawOperand) throws OperandFormatException
{
int operand;
switch (fieldID)
{
case PowerPCInstructionSet.A:
case PowerPCInstructionSet.B:
case PowerPCInstructionSet.D:
operand=parseGpr(rawOperand);
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
return opcode;
case PowerPCInstructionSet.BD:
operand=resolveLabelOrInt(rawOperand);
if ((operand & 3) !=0)
{
warn(ERROR, "Unaligned branch target");
}
if (PowerPCUtils.extractAA(opcode)==0)
{
//System.err.println("Making address " + operand
// + " into displacement " + (operand-getCurrentAddress()));
operand-=getCurrentAddress();
}
if (operand>=Short.MIN_VALUE && operand<=Short.MAX_VALUE)
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand/4);
}
else
{
warn(ERROR, "Branch conditional target out of bounds");
}
return opcode;
case PowerPCInstructionSet.CRFD:
case PowerPCInstructionSet.CRFS:
if (rawOperand.startsWith(crfPrefix))
{
operand=parseInt(rawOperand.substring(crfPrefix.length()));
}
else
{
warn(forceCrfPrefix, "Missing CRF prefix");
operand=parseInt(rawOperand);
}
if (operand>=0 && operand<=7)
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
}
else
{
warn(ERROR, "CR index out of bounds");
}
return opcode;
case PowerPCInstructionSet.LI:
operand=resolveLabelOrInt(rawOperand);
if ((operand & 3) !=0)
{
warn(ERROR, "Unaligned branch displacement");
}
if (PowerPCUtils.extractAA(opcode)==0)
{
//System.err.println("Making address " + operand
// + " into displacement " + (operand-getCurrentAddress()));
operand-=getCurrentAddress();
}
if (operand<=(1<<24) && operand>=-1-(1<<24))
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand/4);
}
else
{
warn(ERROR, "Branch target out of bounds");
}
return opcode;
case PowerPCInstructionSet.SIMM:
operand=resolveLabelOrInt(rawOperand);
if (operand>=Short.MIN_VALUE && operand<=Short.MAX_VALUE)
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
}
else
{
warn(ERROR, "Signed immediate out of bounds");
}
return opcode;
case PowerPCInstructionSet.UIMM:
operand=resolveLabelOrInt(rawOperand);
if (operand>=0 && operand<(1<<16))
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
}
else
{
warn(ERROR, "Unsigned immediate out of bounds");
}
return opcode;
case PowerPCInstructionSet.L:
operand=parseInt(rawOperand);
if (operand==0 || operand==1)
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
return opcode;
}
else
{
warn(ERROR, "Invalid L bit");
}
case PowerPCInstructionSet.SH:
case PowerPCInstructionSet.MB:
case PowerPCInstructionSet.ME:
operand=parseInt(rawOperand);
if (operand>=0 && operand<=31)
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
return opcode;
}
else
{
warn(ERROR, "Rotate operand out of bounds");
}
case PowerPCInstructionSet.SPR:
operand=parseInt(rawOperand);
if (operand==1 || operand==8 || operand==9)
{
// BUG: this ignores the other half of the field, which won't work when
// this is non-zero (i. e. for some of the other SPRs)
opcode|=operand<<16;
//opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
// is.getFieldLength(fieldID)/2, operand);
return opcode;
}
else
{
warn(ERROR, "Unknown SPR");
}
case PowerPCInstructionSet.CRM:
operand=parseInt(rawOperand);
if (operand>=0 && operand<=0xFF)
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
return opcode;
}
else
{
warn(ERROR, "Invalid condition register mask");
}
case PowerPCInstructionSet.BI:
operand=parseInt(rawOperand);
if (operand>=0 && operand<=31)
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
return opcode;
}
else
{
warn(ERROR, "Invalid condition register bit index in branch condition");
}
case PowerPCInstructionSet.BO:
operand=parseInt(rawOperand);
// BUG: could be more exclusive than this?
if (operand>=0 && operand<=31)
{
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
return opcode;
}
else
{
warn(ERROR, "Invalid branch condition option");
}
case PowerPCInstructionSet.A0:
operand=parseA0(rawOperand);
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
return opcode;
case PowerPCInstructionSet.ANOT0:
operand=parseANOT0(rawOperand);
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
return opcode;
case PowerPCInstructionSet.CRBA:
case PowerPCInstructionSet.CRBB:
case PowerPCInstructionSet.CRBD:
operand=parseCrb(rawOperand);
opcode=Utils.setField(opcode, is.getFieldStart(fieldID),
is.getFieldLength(fieldID), operand);
return opcode;
// simplified mnemonics
// some are handled via recursion to ensure the same verification - in which case
// the operand needs to be converted back to a string after manipulation
// [optimize? - could use a instance stringbuffer], including any prefix etc
// some are done manually for simplicity
// BUG: check all prefixes done properly: may have to do more than ""+operand to
// overcome warning as r is required for regs etc.
case SimplifiedPowerPCInstructionSet.NEGSIMM:
operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.SIMM, ""+(-operand));
case SimplifiedPowerPCInstructionSet.DAB:
operand=parseGpr(rawOperand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.D),
is.getFieldLength(PowerPCInstructionSet.D), operand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.A),
is.getFieldLength(PowerPCInstructionSet.A), operand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.B),
is.getFieldLength(PowerPCInstructionSet.B), operand);
return opcode;
case SimplifiedPowerPCInstructionSet.AB:
operand=parseGpr(rawOperand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.A),
is.getFieldLength(PowerPCInstructionSet.A), operand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.B),
is.getFieldLength(PowerPCInstructionSet.B), operand);
return opcode;
case SimplifiedPowerPCInstructionSet.DB:
operand=parseGpr(rawOperand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.D),
is.getFieldLength(PowerPCInstructionSet.D), operand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.B),
is.getFieldLength(PowerPCInstructionSet.B), operand);
return opcode;
case SimplifiedPowerPCInstructionSet.ME_PLUS_1:
operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.ME, ""+(operand-1));
case SimplifiedPowerPCInstructionSet.THIRTY_TWO_MINUS_MB:
operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.MB, ""+(32-operand));
case SimplifiedPowerPCInstructionSet.COMPLETE1:
{
operand=parseInt(rawOperand);
int n=32-PowerPCUtils.extractMB(opcode);
return insertField(opcode, PowerPCInstructionSet.SH, ""+(operand+n));
}
case SimplifiedPowerPCInstructionSet.TEMP_ME:
operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.ME, ""+operand);
case SimplifiedPowerPCInstructionSet.COMPLETE2:
{
operand=parseInt(rawOperand);
opcode=insertField(opcode, PowerPCInstructionSet.MB, ""+operand);
opcode=insertField(opcode, PowerPCInstructionSet.SH, ""+(32-operand));
int n=PowerPCUtils.extractME(opcode);
opcode&=~0x3E; // remove old ME
return insertField(opcode, PowerPCInstructionSet.ME, ""+(operand+n-1));
}
case SimplifiedPowerPCInstructionSet.COMPLETE3:
{
operand=parseInt(rawOperand);
opcode=insertField(opcode, PowerPCInstructionSet.MB, ""+operand);
int n=PowerPCUtils.extractME(opcode);
opcode=insertField(opcode, PowerPCInstructionSet.SH, ""+(32-(operand+n)));
opcode&=~0x3E; // remove old ME
return insertField(opcode, PowerPCInstructionSet.ME, ""+(operand+n-1));
}
case SimplifiedPowerPCInstructionSet.THIRTY_TWO_MINUS_SH:
operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.SH, ""+(32-operand));
case SimplifiedPowerPCInstructionSet.SH_AND_31_MINUS_ME:
operand=parseInt(rawOperand);
return insertField(
insertField(opcode, PowerPCInstructionSet.SH, ""+operand),
PowerPCInstructionSet.ME, ""+(31-operand));
case SimplifiedPowerPCInstructionSet.MB_AND_32_MINUS_SH:
operand=parseInt(rawOperand);
return insertField(
insertField(opcode, PowerPCInstructionSet.MB, ""+operand),
PowerPCInstructionSet.SH, ""+(32-operand));
case SimplifiedPowerPCInstructionSet.THIRTY_ONE_MINUS_ME:
operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.ME, ""+(31-operand));
case SimplifiedPowerPCInstructionSet.COMPLETE4:
{
operand=parseInt(rawOperand);
opcode=insertField(opcode, PowerPCInstructionSet.SH, ""+operand);
int b=PowerPCUtils.extractME(opcode);
opcode&=~0x3E; // remove old ME
opcode=insertField(opcode, PowerPCInstructionSet.MB, ""+(b-operand));
return insertField(opcode, PowerPCInstructionSet.ME, ""+(31-operand));
}
case SimplifiedPowerPCInstructionSet.CRBAB:
operand=parseCrb(rawOperand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBA),
is.getFieldLength(PowerPCInstructionSet.CRBA), operand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBB),
is.getFieldLength(PowerPCInstructionSet.CRBB), operand);
return opcode;
case SimplifiedPowerPCInstructionSet.CRBDAB:
operand=parseCrb(rawOperand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBD),
is.getFieldLength(PowerPCInstructionSet.CRBD), operand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBA),
is.getFieldLength(PowerPCInstructionSet.CRBA), operand);
opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBB),
is.getFieldLength(PowerPCInstructionSet.CRBB), operand);
return opcode;
default:
throw new OperandFormatException("Internal error: Unknown instruction field ("
+ fieldID + ").");
}
}
}
Index: NewAssembler.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/NewAssembler.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** NewAssembler.java 2001/11/22 12:01:07 1.5
--- NewAssembler.java 2001/11/23 10:50:14 1.6
***************
*** 4,46 ****
import java.util.*;
! /** Brand new assembler, fixing most of the design defects of the previous one.
! This version is a single-pass assembler, using back-patches for forward references.
! To do:
! + move "rA"->"A" and "crB"->"B" handling to PowerPCInstructionEncoder
! + check instruction set coding for errors that will cause problems with above (i.e. different types sharing a field ID)
! + e.g. A0... this will probably need going over line by line.
! - check disp(rX) handling
! - allow stuff like "bdnzt eq, target" i.e. make cr bit index aliases - but how to do other crfs "bdnzt 4*cr5+eq, target"?
! (see prog-env appendix F)
! + implement the back-patching required for a single pass assembler (or hook up Preprocessor)
! - write .align, .byte, .double, .float, .long, .llong, .quad (?), .set (?), .short, .space, .string, .vbyte (?)
! - hook it all up to the gui and test
! + remove old assembler stuff that's no longer used (Assembler, Assembling prefs, Glue, PowerPCAssemblingPrefs, Preprocessor (?)
! - document (inc release notes?)
! - release!
*/
! public class NewAssembler
{
! static final String LONG=".long", BYTE=".byte", ALIGN=".align", SPACE=".space", SHORT=".short", SET=".set";
! static final String[] directives={LONG, BYTE, ALIGN, SPACE, SHORT, SET};
/** Warning levels.*/
! static final int IGNORE=0, WARN=1, ERROR=2;
! InstructionSet is;
! Map instructions;
! InstructionEncoder encoder;
! int currentLineNum;
! int currentAddress;
! Map labelTable;
! Parser parser;
! StringBuffer warnings;
! Map aliases;
public NewAssembler(InstructionSet is)
{
this.is=is;
- // BUG: not generic!
- this.encoder=new PowerPCInstructionEncoder(this);
instructions=new HashMap(is.instructions.size()*2);
aliases=new HashMap();
--- 4,42 ----
import java.util.*;
! /** Brand new assembler, fixing most of the design defects of the previous one. This version
! is a single-pass assembler, using back-patches for forward references. This class contains
! the instruction set neutral code. Instruction set specific functionality is to be handled in
! subclasses. Note that the method <code>insertField(int, int, String)</code> is assumed to be
! inherently platform specific and is therefore abstract.
! <p>To do:
! <ul>
! <li>check/fix disp(rX) handling
! <li>allow stuff like "bdnzt eq, target" i.e. make cr bit index aliases - but how to do other
! crfs "bdnzt 4*cr5+eq, target"? (see prog-env appendix F)
! <li>write .double, .float, .llong, .quad (?), .string, .vbyte (?)
! </ul>
! @see #insertField(int, int, String)
*/
! public abstract class NewAssembler
{
! protected static final String LONG=".long", BYTE=".byte", ALIGN=".align",
! SPACE=".space", SHORT=".short", SET=".set";
! protected static final String[] directives={LONG, BYTE, ALIGN, SPACE, SHORT, SET};
/** Warning levels.*/
! protected static final int IGNORE=0, WARN=1, ERROR=2;
! protected InstructionSet is;
! protected Map instructions;
! protected int currentLineNum;
! protected int currentAddress;
! protected Map labelTable;
! protected Parser parser;
! protected StringBuffer warnings;
! protected Map aliases;
public NewAssembler(InstructionSet is)
{
this.is=is;
instructions=new HashMap(is.instructions.size()*2);
aliases=new HashMap();
***************
*** 53,72 ****
}
! int getCurrentAddress()
{
return currentAddress;
}
! int getCurrentLineNum()
{
return currentLineNum;
}
! Integer resolveLabel(String label)
{
return (Integer) labelTable.get(label);
}
! int parseInt(String s) throws OperandFormatException
{
try
--- 49,68 ----
}
! protected int getCurrentAddress()
{
return currentAddress;
}
! protected int getCurrentLineNum()
{
return currentLineNum;
}
! protected Integer resolveLabel(String label)
{
return (Integer) labelTable.get(label);
}
! protected int parseInt(String s) throws OperandFormatException
{
try
***************
*** 83,87 ****
/** This performs the label substitution or literal parsing for branch targets.
Also used to allow things like <code>li rA, label</code> and <code>la rA, label(rB)</code>.*/
! int resolveLabelOrInt(String target) throws OperandFormatException
{
int result;
--- 79,83 ----
/** This performs the label substitution or literal parsing for branch targets.
Also used to allow things like <code>li rA, label</code> and <code>la rA, label(rB)</code>.*/
! protected int resolveLabelOrInt(String target) throws OperandFormatException
{
int result;
***************
*** 106,110 ****
}
! void warn(int option, String message) throws OperandFormatException
{
if (option==1)
--- 102,106 ----
}
! protected void warn(int option, String message) throws OperandFormatException
{
if (option==1)
***************
*** 129,138 ****
}
! /** allow differentiating by both mnemonic and num operands
! Bug: change to offer different versions of it depending on number of operands.
! May involve name mangling... or not: could do it properly and make a comparitor
! that returns a value based on the string comparison unless they match in which
case it also compares the number of operands.*/
! InstructionType lookupInstructionType(String mnemonic, int numOperands) throws AssemblerException
{
//List matchingByMnemonics=someLookupMagic(mnemonic);
--- 125,136 ----
}
! /** The signature of this method suggests that InstructionTypes need be unique with regard to both
! mnemonic and num operands, i.e. that different types with the same mnemonic are allowed provided
! they differ in their number of operands. Currently, this is not yet implemented, so InstructionTypes
! must have a unique mnemonic. This is a BUG in that the feature is used for the simplified PowerPC
! instructions. The fix may involve name mangling, but may not: we could do it properly and make a
! comparitor that returns a value based on the string comparison unless they match in which
case it also compares the number of operands.*/
! protected InstructionType lookupInstructionType(String mnemonic, int numOperands) throws AssemblerException
{
//List matchingByMnemonics=someLookupMagic(mnemonic);
***************
*** 156,160 ****
/** Returns the string matching the given string iff it is contained in the directives array.
Just uses a linear search: the list of possible directives is short.*/
! String lookupDirective(String directive)
{
for (int i=0; i<directives.length; i++)
--- 154,158 ----
/** Returns the string matching the given string iff it is contained in the directives array.
Just uses a linear search: the list of possible directives is short.*/
! protected String lookupDirective(String directive)
{
for (int i=0; i<directives.length; i++)
***************
*** 169,173 ****
/** Returns the aliased value if the argument has been set as an alias, otherwise it returns the argument.*/
! String replaceAliases(String s)
{
String r=(String) aliases.get(s);
--- 167,171 ----
/** Returns the aliased value if the argument has been set as an alias, otherwise it returns the argument.*/
! protected String replaceAliases(String s)
{
String r=(String) aliases.get(s);
***************
*** 176,183 ****
! /** Returns true if the string is empty, the first character is a digit, or it's
! a mnemonic in the current instruction set (since that would mess up our crappy address
! calculation) or if it contains a colon (it's just too confusing for the user).
! Note duplicate labels are handled elsewhere.
ISSUE: May require other checks too?*/
public boolean isIllegalLabel(String s)
--- 174,179 ----
! /** Returns true if the string is empty, the first character is a digit, or it's a mnemonic in the current
! instruction set or contains a colon (it's just too confusing). Note duplicate labels are handled elsewhere.
ISSUE: May require other checks too?*/
public boolean isIllegalLabel(String s)
***************
*** 190,194 ****
@param incompletes A list to which to add a list of AssemblyLines producing an UnknownSymbolException.
If this vlaue if null, a new AssemblerException will be thrown.*/
! void assembleLine(Line line, DataOutput output, List incompletes, int lineNum)
throws AssemblerException, IOException
{
--- 186,190 ----
@param incompletes A list to which to add a list of AssemblyLines producing an UnknownSymbolException.
If this vlaue if null, a new AssemblerException will be thrown.*/
! protected void assembleLine(Line line, DataOutput output, List incompletes, int lineNum)
throws AssemblerException, IOException
{
***************
*** 218,222 ****
for (int i=0; i<it.getNumOperands(); i++)
{
! opcode=encoder.insertField(opcode, it.getOperandField(i),
replaceAliases(line.getOperand(i)));
//System.err.println("Inserting operand " + i + " which is " + line.getOperand(i));
--- 214,218 ----
for (int i=0; i<it.getNumOperands(); i++)
{
! opcode=insertField(opcode, it.getOperandField(i),
replaceAliases(line.getOperand(i)));
//System.err.println("Inserting operand " + i + " which is " + line.getOperand(i));
***************
*** 330,333 ****
--- 326,336 ----
}
+ /** Updates an opcode with a given value inserted into the given field.
+ @param opcode The instruction as it currently is.
+ @param fieldID The identifier of the field, as given by the instruction type data.
+ @param operand The value to be encoded and inserted into the opcode.
+ @return The updated opcode.*/
+ public abstract int insertField(int opcode, int fieldID, String operand) throws OperandFormatException;
+
public byte[] assemble(String s) throws AssemblerException
{
***************
*** 374,378 ****
}
! byte[] backpatch(byte[] data, List incompletes) throws AssemblerException, IOException
{
RandomAccessDataOutput output=new RandomAccessDataOutput(data);
--- 377,381 ----
}
! protected byte[] backpatch(byte[] data, List incompletes) throws AssemblerException, IOException
{
RandomAccessDataOutput output=new RandomAccessDataOutput(data);
--- InstructionEncoder.java DELETED ---
--- PowerPCInstructionEncoder.java DELETED ---
|
|
From: Nigel P. <nph...@us...> - 2001-11-23 10:47:29
|
Update of /cvsroot/exspiminator/exspiminator/docs In directory usw-pr-cvs1:/tmp/cvs-serv23382/docs Modified Files: asm-tutorial.html Log Message: Trivial. Index: asm-tutorial.html =================================================================== RCS file: /cvsroot/exspiminator/exspiminator/docs/asm-tutorial.html,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** asm-tutorial.html 2001/11/21 11:41:30 1.9 --- asm-tutorial.html 2001/11/23 10:47:26 1.10 *************** *** 16,20 **** </ul> ! <p>The GPRs are identified by the names <code>r0</code> to <code>r31</code> and thus there are 32 of them. These registers all function the same way (except <code>r0</code>, which has some special usage which is described in the section "<A HREF="#A0">Special case handling of <code>r0</code></A>") and are used for all integer operations: PowerPC is a "load/store" architecture in that operations on values in memory cannot be done <em>in situ</em>. To add, multiply, xor, or compare integers, etc, we must first load the integers into the GPRs. (Similarly, floating point arithmetic can only be done on the floating point registers.) So to perform an operation on a value in memory, we must load the value, perform the operation, and then store the value back into memory. This separation of instructions involving memory access and those operating on data is just one example of the "loose coupling" of the funtional units implied by the PowerPC instruction set. <p>The functional units in a PowerPC chip are loosely coupled, by which I mean that most instructions affect only one processor unit (there are at least three "units" conceptually: an integer processing unit, a floating point processor unit, and a branch processor unit). Integer operations only involve the GPRs, floating point operations only involve the FPRs, branch operations usually only involve the branch registers (etc). This separation is an efficiency measure: by minimizing the interfaces between functional units, the interdependencies between instructions becomes easier to detect, which increases the opportunites for - and decreases the cost of - executing multiple instructions in parallel (i.e. at the same time). The drawback is that it sometimes makes life more difficult for the programmer... for example there is no interface between the floating point unit and the integer unit except main memory: to transfer a value from a GPR to an FPR you first have to store to RAM and then load it into an FPR. --- 16,20 ---- </ul> ! <p>The GPRs are identified by the names <code>r0</code> to <code>r31</code> and thus there are 32 of them. These registers all function the same way (except <code>r0</code>, which has some special usage which is described in the section "<A HREF="#A0">Special case handling of <code>r0</code></A>") and are used for all integer operations: PowerPC is a "load/store" architecture in that operations on values in memory cannot be done <em>in situ</em>. To add, multiply, xor, or compare integers, etc, we must first load the integers into the GPRs. (Similarly, floating point arithmetic can only be done on the floating point registers.) So to perform an operation on a value in memory, we must load the value, perform the operation, and then store the value back into memory. This separation of instructions involving memory access and those operating on data is just one example of the "loose coupling" of the functional units implied by the PowerPC instruction set. <p>The functional units in a PowerPC chip are loosely coupled, by which I mean that most instructions affect only one processor unit (there are at least three "units" conceptually: an integer processing unit, a floating point processor unit, and a branch processor unit). Integer operations only involve the GPRs, floating point operations only involve the FPRs, branch operations usually only involve the branch registers (etc). This separation is an efficiency measure: by minimizing the interfaces between functional units, the interdependencies between instructions becomes easier to detect, which increases the opportunites for - and decreases the cost of - executing multiple instructions in parallel (i.e. at the same time). The drawback is that it sometimes makes life more difficult for the programmer... for example there is no interface between the floating point unit and the integer unit except main memory: to transfer a value from a GPR to an FPR you first have to store to RAM and then load it into an FPR. *************** *** 42,46 **** <ul> <li>all the load and store operations - to provide easy access to the lowest and highest memory locations - except the "with update" forms, for which using <code>r0</code> as the base register is invalid, as it would be confusing when <code>r0</code> is assumed to be constant (zero) for loads and stores ! <li><code>addi</code> and <code>addis</code> (to provide the <code>li</code> and <code>lis</code> simplified instructions); and <li>the data cache, instruction cache, and external control instructions (for consistency with the load and store instructions). </ul> --- 42,46 ---- <ul> <li>all the load and store operations - to provide easy access to the lowest and highest memory locations - except the "with update" forms, for which using <code>r0</code> as the base register is invalid, as it would be confusing when <code>r0</code> is assumed to be constant (zero) for loads and stores ! <li><code>addi</code> and <code>addis</code> (to provide the <code>li</code>, <code>lis</code>, and <code>la</code> simplified instructions); and <li>the data cache, instruction cache, and external control instructions (for consistency with the load and store instructions). </ul> |
|
From: Nigel P. <nph...@us...> - 2001-11-22 17:39:19
|
Update of /cvsroot/exspiminator/exspiminator/samples In directory usw-pr-cvs1:/tmp/cvs-serv22474/samples Modified Files: triv.txt Log Message: General tidy-up: access modifiers, javadocs etc. Index: triv.txt =================================================================== RCS file: /cvsroot/exspiminator/exspiminator/samples/triv.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** triv.txt 2001/11/19 16:17:49 1.10 --- triv.txt 2001/11/22 17:39:16 1.11 *************** *** 4,7 **** --- 4,8 ---- li r5, 20 li r0, 2 + beq -4 sc addi 5, 5, 2 |
|
From: Nigel P. <nph...@us...> - 2001-11-22 17:39:19
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv22474/base
Modified Files:
AssemblerException.java AssemblyLine.java Line.java
Parser.java
Log Message:
General tidy-up: access modifiers, javadocs etc.
Index: AssemblerException.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/AssemblerException.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** AssemblerException.java 2001/11/19 16:17:49 1.2
--- AssemblerException.java 2001/11/22 17:39:16 1.3
***************
*** 1,5 ****
package exspiminator.base;
! /** Make this a superclass of OperandFormatException.*/
public class AssemblerException extends Exception
{
--- 1,5 ----
package exspiminator.base;
! /** The general type of exceptions that can be thrown by the assembler.*/
public class AssemblerException extends Exception
{
Index: AssemblyLine.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/AssemblyLine.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** AssemblyLine.java 2001/11/19 16:17:49 1.2
--- AssemblyLine.java 2001/11/22 17:39:16 1.3
***************
*** 2,11 ****
/** An encapsulation of a line of Assembly source and an address into which the assembled opcode is to be
! placed. Used for deferred assembly of forward references (and can be used for assembling single lines
! in the GUI?).*/
public class AssemblyLine
{
public Line line;
public int lineNum;
public int address;
--- 2,14 ----
/** An encapsulation of a line of Assembly source and an address into which the assembled opcode is to be
! placed. Used for deferred assembly of forward references. Could also used for assembling single lines
! in the GUI?.*/
public class AssemblyLine
{
+ /** The source to be assembled.*/
public Line line;
+ /** The number of line in the source text. Used so that we can report errors with the appropriate line number.*/
public int lineNum;
+ /** The address at which to assemble the Line.*/
public int address;
Index: Line.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/Line.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** Line.java 2001/11/19 16:17:49 1.2
--- Line.java 2001/11/22 17:39:16 1.3
***************
*** 3,7 ****
import java.util.*;
! /** Note the various data elements will be null (and not empty) for Lines that don't contain them.*/
public class Line
{
--- 3,8 ----
import java.util.*;
! /** A line of assembly language source text, split into its various components.
! Note the various data elements will be null (and not empty) for Lines that don't contain them.*/
public class Line
{
***************
*** 19,22 ****
--- 20,24 ----
}
+ /** This returns the first non label component, such as a mnemonic or assembler directive.*/
public String getMnemonic()
{
Index: Parser.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/Parser.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** Parser.java 2001/11/21 11:39:50 1.4
--- Parser.java 2001/11/22 17:39:16 1.5
***************
*** 3,18 ****
import java.io.*;
! /** Note: handles 4(r3) etc as one operand, this will need recoding in InstructionSet? (also instructionEncoder).*/
! class Parser
{
! //String data;
! /** The index of the next character in the data string to be handled.*/
! //int index;
! String whitespace, commentMarkers, operandSeparators;
! StringBuffer lineBuffer;
! StringBuffer tokenBuffer;
! BufferedReader reader;
!
! Parser(String text, String whites, String comments, String separators)
{
reader=new BufferedReader(new StringReader(text));
--- 3,23 ----
import java.io.*;
! /** The function of this class is to produces a series of <code>Line</code>s from a source text.
! BUG: currently, whitespace is taken as delimiting operands, but comma is the real operand serarator!
! This will have to be fixed before we can have assemble-time arithmetic.
! BUG: Quotes strings are not recognized. We need to handle quotes properly, for the .string directive,
! including the case where the it contains commas, and white space etc.
!
! @see Line*/
! public class Parser
{
! protected String whitespace, commentMarkers, operandSeparators;
! protected StringBuffer lineBuffer;
! protected StringBuffer tokenBuffer;
! protected BufferedReader reader;
!
! /** Creates a parser ready to parse the given text with the given options.
! @param text The source text which is to be parsed.*/
! public Parser(String text, String whites, String comments, String separators)
{
reader=new BufferedReader(new StringReader(text));
***************
*** 24,37 ****
tokenBuffer=new StringBuffer();
}
-
! /** BUG: how to handle commas, spaces (and other whitespace) within operands (as delimited by commas) etc etc
! Currently operands are whitespace delimited, the aim was to have them comma deliminted at some point.*/
! Parser(String text)
{
this(text, " \t\r\f)", ";#", " \t\r\f),(");
}
! boolean isLabel(String s)
{
//System.err.println(s + " is a label? :" + s.endsWith(":"));
--- 29,39 ----
tokenBuffer=new StringBuffer();
}
! public Parser(String text)
{
this(text, " \t\r\f)", ";#", " \t\r\f),(");
}
! protected boolean isLabel(String s)
{
//System.err.println(s + " is a label? :" + s.endsWith(":"));
***************
*** 39,43 ****
}
! String stripLabelMarker(String token)
{
return token.substring(0, token.length()-1);
--- 41,45 ----
}
! protected String stripLabelMarker(String token)
{
return token.substring(0, token.length()-1);
***************
*** 85,89 ****
@return False iff the string has already been read completely (and thus <code>to</code> contains
garbage).*/
! boolean readLine(StringBuffer to) throws IOException
{
boolean done=false;
--- 87,91 ----
@return False iff the string has already been read completely (and thus <code>to</code> contains
garbage).*/
! protected boolean readLine(StringBuffer to) throws IOException
{
boolean done=false;
***************
*** 107,111 ****
@param delimeters A String any character of which would mark the end of a token.
@return The token, or null if none in the buffer.*/
! String getNextToken(StringBuffer buffy, String delimeters)
{
tokenBuffer.setLength(0);
--- 109,113 ----
@param delimeters A String any character of which would mark the end of a token.
@return The token, or null if none in the buffer.*/
! protected String getNextToken(StringBuffer buffy, String delimeters)
{
tokenBuffer.setLength(0);
***************
*** 137,145 ****
}
! /** Removes any comment from the line contained in the given StringBuffer.
Note the relationship between this and getNextToken - it handles everything <em>before</em> a
delimeter, this handles everthing <em>after</em> one.
@return The comment, or null if none.*/
! static String getComment(StringBuffer buffy, String delimeters)
{
String result=null;
--- 139,148 ----
}
! /** Removes any comment from the line contained in the given StringBuffer, and returns it (minus the comment
! marker) in the given StringBuffer.
Note the relationship between this and getNextToken - it handles everything <em>before</em> a
delimeter, this handles everthing <em>after</em> one.
@return The comment, or null if none.*/
! protected static String getComment(StringBuffer buffy, String delimeters)
{
String result=null;
|
|
From: Nigel P. <nph...@us...> - 2001-11-22 12:08:03
|
Update of /cvsroot/exspiminator/exspiminator/docs In directory usw-pr-cvs1:/tmp/cvs-serv29304/docs Modified Files: tutorial.html Log Message: Add .set Index: tutorial.html =================================================================== RCS file: /cvsroot/exspiminator/exspiminator/docs/tutorial.html,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** tutorial.html 2001/11/20 12:00:10 1.7 --- tutorial.html 2001/11/22 12:01:07 1.8 *************** *** 38,41 **** --- 38,42 ---- <tr><td><code>.byte <em>N1, N2, [...] Nn</em></code><td>Stores the least significant byte of the given value(s) into the object code. <tr><td><code>.long <em>N1, N2, [...] Nn</em></code><td>Stores the value(s) into the object code. + <tr><td><code>.set <em>name, value</em></code><td>Allows a value to be referred to by the given name. <tr><td><code>.short <em>N1, N2, [...] Nn</em></code><td>Stores the least significant half word of the given value(s) into the object code. <tr><td><code>.space <em>N</em></code><td>Sets aside space in the object code by inserting <em>N</em> bytes of value 0. |
|
From: Nigel P. <nph...@us...> - 2001-11-22 12:08:03
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv29304/base
Modified Files:
NewAssembler.java
Log Message:
Add .set
Index: NewAssembler.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/NewAssembler.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** NewAssembler.java 2001/11/20 12:17:49 1.4
--- NewAssembler.java 2001/11/22 12:01:07 1.5
***************
*** 12,19 ****
+ e.g. A0... this will probably need going over line by line.
- check disp(rX) handling
+ implement the back-patching required for a single pass assembler (or hook up Preprocessor)
- write .align, .byte, .double, .float, .long, .llong, .quad (?), .set (?), .short, .space, .string, .vbyte (?)
- hook it all up to the gui and test
! - remove old assembler stuff that's no longer used (Assembler, Assembling prefs, Glue, PowerPCAssemblingPrefs, Preprocessor (?)
- document (inc release notes?)
- release!
--- 12,21 ----
+ e.g. A0... this will probably need going over line by line.
- check disp(rX) handling
+ - allow stuff like "bdnzt eq, target" i.e. make cr bit index aliases - but how to do other crfs "bdnzt 4*cr5+eq, target"?
+ (see prog-env appendix F)
+ implement the back-patching required for a single pass assembler (or hook up Preprocessor)
- write .align, .byte, .double, .float, .long, .llong, .quad (?), .set (?), .short, .space, .string, .vbyte (?)
- hook it all up to the gui and test
! + remove old assembler stuff that's no longer used (Assembler, Assembling prefs, Glue, PowerPCAssemblingPrefs, Preprocessor (?)
- document (inc release notes?)
- release!
***************
*** 21,26 ****
public class NewAssembler
{
! static final String LONG=".long", BYTE=".byte", ALIGN=".align", SPACE=".space", SHORT=".short";
! static final String[] directives={LONG, BYTE, ALIGN, SPACE, SHORT};
/** Warning levels.*/
static final int IGNORE=0, WARN=1, ERROR=2;
--- 23,28 ----
public class NewAssembler
{
! static final String LONG=".long", BYTE=".byte", ALIGN=".align", SPACE=".space", SHORT=".short", SET=".set";
! static final String[] directives={LONG, BYTE, ALIGN, SPACE, SHORT, SET};
/** Warning levels.*/
static final int IGNORE=0, WARN=1, ERROR=2;
***************
*** 34,37 ****
--- 36,40 ----
Parser parser;
StringBuffer warnings;
+ Map aliases;
public NewAssembler(InstructionSet is)
***************
*** 41,44 ****
--- 44,48 ----
this.encoder=new PowerPCInstructionEncoder(this);
instructions=new HashMap(is.instructions.size()*2);
+ aliases=new HashMap();
for (int i=0; i<is.instructions.size(); i++)
{
***************
*** 64,68 ****
}
- /** Modify to allow alises at some point?*/
int parseInt(String s) throws OperandFormatException
{
--- 68,71 ----
***************
*** 79,84 ****
/** This performs the label substitution or literal parsing for branch targets.
! Also used to allow things like <code>li rA, label</code> and <code>la rA, label(rB)</code>.
! BUG: remember we'll have to deal with aliases too at some point.*/
int resolveLabelOrInt(String target) throws OperandFormatException
{
--- 82,86 ----
/** This performs the label substitution or literal parsing for branch targets.
! Also used to allow things like <code>li rA, label</code> and <code>la rA, label(rB)</code>.*/
int resolveLabelOrInt(String target) throws OperandFormatException
{
***************
*** 166,169 ****
--- 168,179 ----
}
+ /** Returns the aliased value if the argument has been set as an alias, otherwise it returns the argument.*/
+ String replaceAliases(String s)
+ {
+ String r=(String) aliases.get(s);
+ return r!=null ? r : s;
+ }
+
+
/** Returns true if the string is empty, the first character is a digit, or it's
a mnemonic in the current instruction set (since that would mess up our crappy address
***************
*** 208,212 ****
for (int i=0; i<it.getNumOperands(); i++)
{
! opcode=encoder.insertField(opcode, it.getOperandField(i), line.getOperand(i));
//System.err.println("Inserting operand " + i + " which is " + line.getOperand(i));
}
--- 218,223 ----
for (int i=0; i<it.getNumOperands(); i++)
{
! opcode=encoder.insertField(opcode, it.getOperandField(i),
! replaceAliases(line.getOperand(i)));
//System.err.println("Inserting operand " + i + " which is " + line.getOperand(i));
}
***************
*** 239,243 ****
for (int i=0; i<line.getNumOperands(); i++)
{
! output.writeInt(parseInt(line.getOperand(i)));
currentAddress+=4;
}
--- 250,254 ----
for (int i=0; i<line.getNumOperands(); i++)
{
! output.writeInt(parseInt(replaceAliases(line.getOperand(i))));
currentAddress+=4;
}
***************
*** 247,251 ****
for (int i=0; i<line.getNumOperands(); i++)
{
! output.writeByte(parseInt(line.getOperand(i)));
currentAddress+=1;
}
--- 258,262 ----
for (int i=0; i<line.getNumOperands(); i++)
{
! output.writeByte(parseInt(replaceAliases(line.getOperand(i))));
currentAddress+=1;
}
***************
*** 259,263 ****
+ currentLineNum);
}
! int operand=parseInt(line.getOperand(0));
if (operand<0 || operand>3)
{
--- 270,274 ----
+ currentLineNum);
}
! int operand=parseInt(replaceAliases(line.getOperand(0)));
if (operand<0 || operand>3)
{
***************
*** 286,290 ****
+ currentLineNum);
}
! int operand=parseInt(line.getOperand(0));
while (operand>0)
{
--- 297,301 ----
+ currentLineNum);
}
! int operand=parseInt(replaceAliases(line.getOperand(0)));
while (operand>0)
{
***************
*** 298,305 ****
for (int i=0; i<line.getNumOperands(); i++)
{
! output.writeShort(parseInt(line.getOperand(i)));
currentAddress+=2;
}
}
// else we don't handle it yet
}
--- 309,329 ----
for (int i=0; i<line.getNumOperands(); i++)
{
! output.writeShort(parseInt(replaceAliases(line.getOperand(i))));
currentAddress+=2;
}
}
+ else if (directive==SET)
+ {
+ if (line.getNumOperands()!=2)
+ {
+ throw new AssemblerException("Wrong number of operands ("
+ + line.getNumOperands() + " found, 2 expected) at line "
+ + currentLineNum);
+ }
+ if (aliases.put(line.getOperand(0), replaceAliases(line.getOperand(1)))!=null)
+ {
+ throw new AssemblerException("Duplicate alias at line " + currentLineNum);
+ }
+ }
// else we don't handle it yet
}
***************
*** 317,320 ****
--- 341,345 ----
warnings.setLength(0);
labelTable=labels;
+ aliases.clear();
List incompletes=new ArrayList(100);
ByteArrayOutputStream buffy=new ByteArrayOutputStream();
|
|
From: Nigel P. <nph...@us...> - 2001-11-22 12:02:53
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv29725/base
Modified Files:
RandomAccessDataOutput.java
Log Message:
Add short support. Does anything use this anyway?
Index: RandomAccessDataOutput.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/RandomAccessDataOutput.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** RandomAccessDataOutput.java 2001/11/19 16:17:49 1.2
--- RandomAccessDataOutput.java 2001/11/22 12:02:49 1.3
***************
*** 95,102 ****
}
! /** Nop.*/
public void writeShort(int v)
{
! // BUG, if this functionality is expected.
}
--- 95,102 ----
}
! /** Implemented.*/
public void writeShort(int v)
{
! m.setHalfWord(location, v);
}
|
|
From: Nigel P. <nph...@us...> - 2001-11-22 12:02:12
|
Update of /cvsroot/exspiminator/exspiminator/docs In directory usw-pr-cvs1:/tmp/cvs-serv29591/docs Modified Files: release.html Log Message: Note lack of variable operand simplified branch mnemonic support. Index: release.html =================================================================== RCS file: /cvsroot/exspiminator/exspiminator/docs/release.html,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** release.html 2001/11/20 12:01:17 1.21 --- release.html 2001/11/22 12:02:07 1.22 *************** *** 214,218 **** + b[t/f][/a/l/la] + bd[z/nz/nzt/nzf/zt/zf][/a/l/la] ! + b[lt/gt/eq/so/nl/ng/ne/ns/ge/le/un/nu][/l/a/la] + b[lt/gt/eq/so/nl/ng/ne/ns/ge/le/un/nu]lr[/l] + blr[/l], btlr[/l], bflr[/l] --- 214,218 ---- + b[t/f][/a/l/la] + bd[z/nz/nzt/nzf/zt/zf][/a/l/la] ! + b[lt/gt/eq/so/nl/ng/ne/ns/ge/le/un/nu][/l/a/la] (one operand version only) + b[lt/gt/eq/so/nl/ng/ne/ns/ge/le/un/nu]lr[/l] + blr[/l], btlr[/l], bflr[/l] |
|
From: Nigel P. <nph...@us...> - 2001-11-22 11:59:14
|
Update of /cvsroot/exspiminator/exspiminator/gui
In directory usw-pr-cvs1:/tmp/cvs-serv28832/gui
Modified Files:
GUI.java
Log Message:
Comment out unused save code.
Index: GUI.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/gui/GUI.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -r1.23 -r1.24
*** GUI.java 2001/11/20 11:58:59 1.23
--- GUI.java 2001/11/22 11:59:10 1.24
***************
*** 338,342 ****
}
}
!
void save()
{
--- 338,342 ----
}
}
! /*
void save()
{
***************
*** 355,359 ****
}
}
! }
/** Read the data from the file, assuming it to contain [whatever I save] serialized
--- 355,359 ----
}
}
! }*/
/** Read the data from the file, assuming it to contain [whatever I save] serialized
***************
*** 498,503 ****
}
! /** Writes the data to the given path.*/
! void writeData(String filename) throws IOException
{
FileOutputStream file=null;
--- 498,503 ----
}
! /* Writes the data to the given path.*/
! /*void writeData(String filename) throws IOException
{
FileOutputStream file=null;
***************
*** 523,527 ****
{}
}
! }
void refreshRegViews()
--- 523,527 ----
{}
}
! }*/
void refreshRegViews()
|
|
From: Nigel P. <nph...@us...> - 2001-11-21 11:41:33
|
Update of /cvsroot/exspiminator/exspiminator/docs In directory usw-pr-cvs1:/tmp/cvs-serv17947/docs Modified Files: asm-tutorial.html Log Message: Fix spelling. Index: asm-tutorial.html =================================================================== RCS file: /cvsroot/exspiminator/exspiminator/docs/asm-tutorial.html,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** asm-tutorial.html 2001/11/19 16:17:49 1.8 --- asm-tutorial.html 2001/11/21 11:41:30 1.9 *************** *** 16,20 **** </ul> ! <p>The GPRs are identified by the names <code>r0</code> to <code>r31</code> and thus there are 32 of them. These registers all function the same way (except <code>r0</code>, which has some special usage which is described in the section "<A HREF="#A0">Special case handling of <code>r0</code></A>") and are used for all integer operations: PowerPC is a "load/store" architecture in that operations on values in memory cannot be done <em>in situ</em>. To add, multiply, xor, or compare integers, etc, we must first load the integers into the GPRs. (Similarly, floating point arithmetic can only be done on the floating point registers.) So to perform an operation on a value in memory, we must load the value, perform the operation, and then store the value back into memory. This separation of instructions involving memory access and those operating on data is just one example of the "loose coupling" of the funtional untis implied by the PowerPC instruction set. <p>The functional units in a PowerPC chip are loosely coupled, by which I mean that most instructions affect only one processor unit (there are at least three "units" conceptually: an integer processing unit, a floating point processor unit, and a branch processor unit). Integer operations only involve the GPRs, floating point operations only involve the FPRs, branch operations usually only involve the branch registers (etc). This separation is an efficiency measure: by minimizing the interfaces between functional units, the interdependencies between instructions becomes easier to detect, which increases the opportunites for - and decreases the cost of - executing multiple instructions in parallel (i.e. at the same time). The drawback is that it sometimes makes life more difficult for the programmer... for example there is no interface between the floating point unit and the integer unit except main memory: to transfer a value from a GPR to an FPR you first have to store to RAM and then load it into an FPR. --- 16,20 ---- </ul> ! <p>The GPRs are identified by the names <code>r0</code> to <code>r31</code> and thus there are 32 of them. These registers all function the same way (except <code>r0</code>, which has some special usage which is described in the section "<A HREF="#A0">Special case handling of <code>r0</code></A>") and are used for all integer operations: PowerPC is a "load/store" architecture in that operations on values in memory cannot be done <em>in situ</em>. To add, multiply, xor, or compare integers, etc, we must first load the integers into the GPRs. (Similarly, floating point arithmetic can only be done on the floating point registers.) So to perform an operation on a value in memory, we must load the value, perform the operation, and then store the value back into memory. This separation of instructions involving memory access and those operating on data is just one example of the "loose coupling" of the funtional units implied by the PowerPC instruction set. <p>The functional units in a PowerPC chip are loosely coupled, by which I mean that most instructions affect only one processor unit (there are at least three "units" conceptually: an integer processing unit, a floating point processor unit, and a branch processor unit). Integer operations only involve the GPRs, floating point operations only involve the FPRs, branch operations usually only involve the branch registers (etc). This separation is an efficiency measure: by minimizing the interfaces between functional units, the interdependencies between instructions becomes easier to detect, which increases the opportunites for - and decreases the cost of - executing multiple instructions in parallel (i.e. at the same time). The drawback is that it sometimes makes life more difficult for the programmer... for example there is no interface between the floating point unit and the integer unit except main memory: to transfer a value from a GPR to an FPR you first have to store to RAM and then load it into an FPR. |
|
From: Nigel P. <nph...@us...> - 2001-11-21 11:39:54
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv17558/base
Modified Files:
Parser.java
Log Message:
Remove misleading comment.
Index: Parser.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/Parser.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** Parser.java 2001/11/20 12:19:27 1.3
--- Parser.java 2001/11/21 11:39:50 1.4
***************
*** 46,50 ****
/** Parses the next line from the String and returns it as a Line object, or null if the
end of the string has already been reached.*/
- // bug: doesn't handle leading whitespace (???)
public Line parse() throws IOException
{
--- 46,49 ----
|
|
From: Nigel P. <nph...@us...> - 2001-11-20 13:16:17
|
Update of /cvsroot/exspiminator/exspiminator/base In directory usw-pr-cvs1:/tmp/cvs-serv16264/base Removed Files: Assembler.java AssemblingPrefs.java Glue.java PowerPCAssemblingPrefs.java Preprocessor.java Log Message: Removed old assembler stuff now that we have the new assembler. --- Assembler.java DELETED --- --- AssemblingPrefs.java DELETED --- --- Glue.java DELETED --- --- PowerPCAssemblingPrefs.java DELETED --- --- Preprocessor.java DELETED --- |
|
From: Nigel P. <nph...@us...> - 2001-11-20 12:19:30
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv3012/base
Modified Files:
Parser.java
Log Message:
Move exception handling further up the chain - tider.
Index: Parser.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/Parser.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** Parser.java 2001/11/19 16:17:49 1.2
--- Parser.java 2001/11/20 12:19:27 1.3
***************
*** 46,51 ****
/** Parses the next line from the String and returns it as a Line object, or null if the
end of the string has already been reached.*/
! // bug: doesn't handle leading whitespace
! public Line parse()
{
Line result=null;
--- 46,51 ----
/** Parses the next line from the String and returns it as a Line object, or null if the
end of the string has already been reached.*/
! // bug: doesn't handle leading whitespace (???)
! public Line parse() throws IOException
{
Line result=null;
***************
*** 86,112 ****
@return False iff the string has already been read completely (and thus <code>to</code> contains
garbage).*/
! boolean readLine(StringBuffer to)
{
boolean done=false;
to.setLength(0);
! try
{
! String s=reader.readLine();
! if (s==null)
! {
! reader.close();
! return false;
! }
! else
! {
! to.append(s);
! return true;
! }
}
! catch(IOException ex)
{
! // BUG: Could allow this exception propogate back up to NewAssembler.assemble... tidier?
! System.err.println("Internal error: reader produced IOException");
! return false;
}
}
--- 86,103 ----
@return False iff the string has already been read completely (and thus <code>to</code> contains
garbage).*/
! boolean readLine(StringBuffer to) throws IOException
{
boolean done=false;
to.setLength(0);
! String s=reader.readLine();
! if (s==null)
{
! reader.close();
! return false;
}
! else
{
! to.append(s);
! return true;
}
}
|
|
From: Nigel P. <nph...@us...> - 2001-11-20 12:17:52
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv2585/base
Modified Files:
SimplifiedPowerPCInstructionSet.java
PowerPCInstructionEncoder.java NewAssembler.java
Log Message:
Fixed some type errors in ISA data, fixed comments, moved some generic code to the assembler, added warning logging.
Index: SimplifiedPowerPCInstructionSet.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/SimplifiedPowerPCInstructionSet.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** SimplifiedPowerPCInstructionSet.java 2001/11/19 16:17:49 1.6
--- SimplifiedPowerPCInstructionSet.java 2001/11/20 12:17:49 1.7
***************
*** 16,55 ****
public abstract class SimplifiedPowerPCInstructionSet extends PowerPCInstructionSet
{
! /** A value to be negated before putting into the SIMM field.*/
public static final int NEGSIMM=-1;
! /** A value to put in D, A, and B fields.*/
public static final int DAB=-2;
! /** A value to be put in A and B fields.*/
public static final int AB=-3;
! /** A value to be put in D and B fields.*/
public static final int DB=-4;
! /** A value from which one is to be subtracted before insertion into the ME field.*/
public static final int ME_PLUS_1=-5;
! /** A value which is to be subtracted from 32 and then stored in the MB field.*/
public static final int THIRTY_TWO_MINUS_MB=-6;
! /** A value which is to be added to the value of thirty-two minus the contents of the MB field,
! and stored in the SH field.*/
public static final int COMPLETE1=-7;
! /** A value which is to be temporarily store in ME, but is not the correct value for that field.*/
public static final int TEMP_ME=-8;
! /** A value which is the MB field, and 32 minus SH, and which is to trigger replacement of the value
! in the ME field by its current value plus this value minus 1.*/
public static final int COMPLETE2=-9;
! /** A value which is the MB field, and 32 minus (SH plus ME), and which is to trigger replacement
! of the value in the ME field by its current value plus this value minus 1.*/
public static final int COMPLETE3=-10;
! /** A value which is to be subtracted from 32 and then inserted into the SH field.*/
public static final int THIRTY_TWO_MINUS_SH=-11;
! /** A value which is to be put into the SH field and then subtacted from 31 and put into the ME field.*/
public static final int SH_AND_31_MINUS_ME=-12;
! /** A value which is the MB field, and 32 minus SH.*/
public static final int MB_AND_32_MINUS_SH=-13;
! /** A value which is to be subtacted from 31 and put into the ME field.*/
public static final int THIRTY_ONE_MINUS_ME=-14;
! /** A value which is the SH field, to set MB to ME minus this, to clear ME and set it to 31 minus
! this value.*/
public static final int COMPLETE4=-15;
-
private static InstructionSet INSTANCE;
public static InstructionSet getInstructionSet()
--- 16,60 ----
public abstract class SimplifiedPowerPCInstructionSet extends PowerPCInstructionSet
{
! /** This field contains a value to be negated before being placed into the SIMM field.*/
public static final int NEGSIMM=-1;
! /** This field contains a GPR index to be placed in the D, A, and B fields.*/
public static final int DAB=-2;
! /** This field contains a GPR index to be placed in the A and B fields.*/
public static final int AB=-3;
! /** This field contains a GPR index to be placed in the D and B fields.*/
public static final int DB=-4;
! /** This field contains a value from which one is to be subtracted before insertion into the ME field.*/
public static final int ME_PLUS_1=-5;
! /** This field contains a value which is to be subtracted from 32 and then stored in the MB field.*/
public static final int THIRTY_TWO_MINUS_MB=-6;
! /** This field contains a value which is to be added to the value of thirty-two minus the contents of
! the MB field, and stored in the SH field.*/
public static final int COMPLETE1=-7;
! /** This field contains a value which is to be temporarily stored in ME, but is not the correct value for
! that field.*/
public static final int TEMP_ME=-8;
! /** This field contains a value which is the MB field, and 32 minus SH, and which is to trigger
! replacement of the value in the ME field by its current value plus this value minus 1.*/
public static final int COMPLETE2=-9;
! /** This field contains a value which is the MB field, and 32 minus (SH plus ME), and which is to
! trigger replacement of the value in the ME field by its current value plus this value minus 1.*/
public static final int COMPLETE3=-10;
! /** This field contains a value which is to be subtracted from 32 and then inserted into the SH field.*/
public static final int THIRTY_TWO_MINUS_SH=-11;
! /** This field contains a value which is to be put into the SH field and then subtacted from 31 and put
! into the ME field.*/
public static final int SH_AND_31_MINUS_ME=-12;
! /** This field contains a value which is the MB field, and 32 minus SH.*/
public static final int MB_AND_32_MINUS_SH=-13;
! /** This field contains a value which is to be subtacted from 31 and put into the ME field.*/
public static final int THIRTY_ONE_MINUS_ME=-14;
! /** This field contains a value which is the SH field, to set MB to ME minus this, to clear ME and set
! it to 31 minus this value.*/
public static final int COMPLETE4=-15;
+ /** This field contains a condition register bit to be placed in the CRBA and CRBB fields.*/
+ public static final int CRBAB=-16;
+ /** This field contains a condition register bit to be placed in the CRBD, CRBA, and CRBB fields.*/
+ public static final int CRBDAB=-17;
private static InstructionSet INSTANCE;
public static InstructionSet getInstructionSet()
***************
*** 90,94 ****
c.add(new InstructionType("lis", new int[] {1, PRIMARY, 15, D, SIMM}));
// BUG: not two operand version
! c.add(new InstructionType("la", new int[] {1, PRIMARY, 14, D, SIMM, A}));
// integer arithmetic
putDotForm(c, "sub", new int[] {2, PRIMARY, 31, EXTENDED, 40<<1, D, B, A});
--- 95,99 ----
c.add(new InstructionType("lis", new int[] {1, PRIMARY, 15, D, SIMM}));
// BUG: not two operand version
! c.add(new InstructionType("la", new int[] {1, PRIMARY, 14, D, SIMM, A0}));
// integer arithmetic
putDotForm(c, "sub", new int[] {2, PRIMARY, 31, EXTENDED, 40<<1, D, B, A});
***************
*** 96,103 ****
c.add(new InstructionType("subis", new int[] {1, PRIMARY, 15, D, A, NEGSIMM}));
// condition register logical
! c.add(new InstructionType("crset", new int[] {2, PRIMARY, 19, EXTENDED, 289<<1, DAB}));
! c.add(new InstructionType("crclr", new int[] {2, PRIMARY, 19, EXTENDED, 193<<1, DAB}));
! c.add(new InstructionType("crmove", new int[] {2, PRIMARY, 19, EXTENDED, 449<<1, D, AB}));
! c.add(new InstructionType("crnot", new int[] {2, PRIMARY, 19, EXTENDED, 33<<1, D, AB}));
// processor control
c.add(new InstructionType("mtcr", new int[] {3, PRIMARY, 31, EXTENDED, 144<<1, CRM, 255, D}));
--- 101,108 ----
c.add(new InstructionType("subis", new int[] {1, PRIMARY, 15, D, A, NEGSIMM}));
// condition register logical
! c.add(new InstructionType("crset", new int[] {2, PRIMARY, 19, EXTENDED, 289<<1, CRBDAB}));
! c.add(new InstructionType("crclr", new int[] {2, PRIMARY, 19, EXTENDED, 193<<1, CRBDAB}));
! c.add(new InstructionType("crmove", new int[] {2, PRIMARY, 19, EXTENDED, 449<<1, CRBD, CRBAB}));
! c.add(new InstructionType("crnot", new int[] {2, PRIMARY, 19, EXTENDED, 33<<1, CRBD, CRBAB}));
// processor control
c.add(new InstructionType("mtcr", new int[] {3, PRIMARY, 31, EXTENDED, 144<<1, CRM, 255, D}));
Index: PowerPCInstructionEncoder.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/PowerPCInstructionEncoder.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** PowerPCInstructionEncoder.java 2001/11/19 19:17:00 1.3
--- PowerPCInstructionEncoder.java 2001/11/20 12:17:49 1.4
***************
*** 2,8 ****
/** An implementation of InstructionEncoder for the PowerPC.
- BUG: always treats register "A" as a register, even when the value of A is zero (remember some instructions
- use r0 to mean 0 and not a register... these instructions will have to be coded differently e.g. as having
- an "A0" field instead of an "A" field. The disassembler - and assembler too! - can then make use of it)
*/
public class PowerPCInstructionEncoder implements InstructionEncoder
--- 2,5 ----
***************
*** 15,19 ****
String crbPrefix;
- static final int IGNORE=0, WARN=1, ERROR=2;
int forceGprPrefix;
int forceCrfPrefix;
--- 12,15 ----
***************
*** 37,45 ****
this.asm=asm;
gprPrefix="r";
! forceGprPrefix=WARN;
crfPrefix="cr";
! forceCrfPrefix=WARN;
crbPrefix="crb";
! forceCrbPrefix=WARN;
}
--- 33,41 ----
this.asm=asm;
gprPrefix="r";
! forceGprPrefix=asm.WARN;
crfPrefix="cr";
! forceCrfPrefix=asm.WARN;
crbPrefix="crb";
! forceCrbPrefix=asm.WARN;
}
***************
*** 53,62 ****
else
{
! warn(forceGprPrefix, "Missing GPR prefix");
result=asm.parseInt(s);
}
if (result<0 || result>31)
{
! warn(ERROR, "GPR index out of bounds");
}
return result;
--- 49,58 ----
else
{
! asm.warn(forceGprPrefix, "Missing GPR prefix");
result=asm.parseInt(s);
}
if (result<0 || result>31)
{
! asm.warn(asm.ERROR, "GPR index out of bounds");
}
return result;
***************
*** 83,87 ****
if (prefixed==0)
{
! warn(WARN, "Register 0 specified where literal 0 will be coded");
}
return prefixed;
--- 79,83 ----
if (prefixed==0)
{
! asm.warn(asm.WARN, "Register 0 specified where literal 0 will be coded");
}
return prefixed;
***************
*** 94,98 ****
if (result==0)
{
! warn(ERROR, "Register 0 is invalid as a base register in the instruction");
}
return result;
--- 90,94 ----
if (result==0)
{
! asm.warn(asm.ERROR, "Register 0 is invalid as a base register in the instruction");
}
return result;
***************
*** 109,134 ****
else
{
! warn(forceCrbPrefix, "Missing CRB prefix (" + crbPrefix + ")");
result=asm.parseInt(s);
}
if (result<0 || result>31)
{
! warn(ERROR, "CRB index out of bounds");
}
return result;
}
-
- void warn(int option, String message) throws OperandFormatException
- {
- if (option==1)
- {
- System.err.println("Warning: " + message + " at line " + asm.getCurrentLineNum()+".");
- }
- else if (option==2)
- {
- throw new OperandFormatException(message + " at line " + asm.getCurrentLineNum()+".");
- }
- // default: ignore
- }
/** Could be optimized by insertXXX equivalents of PowerPCUtils.extractXXX stuff.
--- 105,117 ----
else
{
! asm.warn(forceCrbPrefix, "Missing CRB prefix (" + crbPrefix + ")");
result=asm.parseInt(s);
}
if (result<0 || result>31)
{
! asm.warn(asm.ERROR, "CRB index out of bounds");
}
return result;
}
/** Could be optimized by insertXXX equivalents of PowerPCUtils.extractXXX stuff.
***************
*** 154,158 ****
if ((operand & 3) !=0)
{
! warn(ERROR, "Unaligned branch target");
}
if (PowerPCUtils.extractAA(opcode)==0)
--- 137,141 ----
if ((operand & 3) !=0)
{
! asm.warn(asm.ERROR, "Unaligned branch target");
}
if (PowerPCUtils.extractAA(opcode)==0)
***************
*** 169,173 ****
else
{
! warn(ERROR, "Branch conditional target out of bounds");
}
return opcode;
--- 152,156 ----
else
{
! asm.warn(asm.ERROR, "Branch conditional target out of bounds");
}
return opcode;
***************
*** 181,185 ****
else
{
! warn(forceCrfPrefix, "Missing CRF prefix");
operand=asm.parseInt(rawOperand);
}
--- 164,168 ----
else
{
! asm.warn(forceCrfPrefix, "Missing CRF prefix");
operand=asm.parseInt(rawOperand);
}
***************
*** 191,195 ****
else
{
! warn(ERROR, "CR index out of bounds");
}
return opcode;
--- 174,178 ----
else
{
! asm.warn(asm.ERROR, "CR index out of bounds");
}
return opcode;
***************
*** 199,203 ****
if ((operand & 3) !=0)
{
! warn(ERROR, "Unaligned branch displacement");
}
if (PowerPCUtils.extractAA(opcode)==0)
--- 182,186 ----
if ((operand & 3) !=0)
{
! asm.warn(asm.ERROR, "Unaligned branch displacement");
}
if (PowerPCUtils.extractAA(opcode)==0)
***************
*** 214,218 ****
else
{
! warn(ERROR, "Branch target out of bounds");
}
return opcode;
--- 197,201 ----
else
{
! asm.warn(asm.ERROR, "Branch target out of bounds");
}
return opcode;
***************
*** 227,231 ****
else
{
! warn(ERROR, "Signed immediate out of bounds");
}
return opcode;
--- 210,214 ----
else
{
! asm.warn(asm.ERROR, "Signed immediate out of bounds");
}
return opcode;
***************
*** 240,244 ****
else
{
! warn(ERROR, "Unsigned immediate out of bounds");
}
return opcode;
--- 223,227 ----
else
{
! asm.warn(asm.ERROR, "Unsigned immediate out of bounds");
}
return opcode;
***************
*** 254,258 ****
else
{
! warn(ERROR, "Invalid L bit");
}
--- 237,241 ----
else
{
! asm.warn(asm.ERROR, "Invalid L bit");
}
***************
*** 269,273 ****
else
{
! warn(ERROR, "Rotate operand out of bounds");
}
--- 252,256 ----
else
{
! asm.warn(asm.ERROR, "Rotate operand out of bounds");
}
***************
*** 285,289 ****
else
{
! warn(ERROR, "Unknown SPR");
}
--- 268,272 ----
else
{
! asm.warn(asm.ERROR, "Unknown SPR");
}
***************
*** 298,302 ****
else
{
! warn(ERROR, "Invalid condition register mask");
}
--- 281,285 ----
else
{
! asm.warn(asm.ERROR, "Invalid condition register mask");
}
***************
*** 311,315 ****
else
{
! warn(ERROR, "Invalid condition register bit index in branch condition");
}
--- 294,298 ----
else
{
! asm.warn(asm.ERROR, "Invalid condition register bit index in branch condition");
}
***************
*** 325,329 ****
else
{
! warn(ERROR, "Invalid branch condition option");
}
--- 308,312 ----
else
{
! asm.warn(asm.ERROR, "Invalid branch condition option");
}
***************
*** 453,456 ****
--- 436,457 ----
return insertField(opcode, PowerPCInstructionSet.ME, ""+(31-operand));
}
+
+ case SimplifiedPowerPCInstructionSet.CRBAB:
+ operand=parseCrb(rawOperand);
+ opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBA),
+ is.getFieldLength(PowerPCInstructionSet.CRBA), operand);
+ opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBB),
+ is.getFieldLength(PowerPCInstructionSet.CRBB), operand);
+ return opcode;
+
+ case SimplifiedPowerPCInstructionSet.CRBDAB:
+ operand=parseCrb(rawOperand);
+ opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBD),
+ is.getFieldLength(PowerPCInstructionSet.CRBD), operand);
+ opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBA),
+ is.getFieldLength(PowerPCInstructionSet.CRBA), operand);
+ opcode=Utils.setField(opcode, is.getFieldStart(PowerPCInstructionSet.CRBB),
+ is.getFieldLength(PowerPCInstructionSet.CRBB), operand);
+ return opcode;
default:
Index: NewAssembler.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/NewAssembler.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** NewAssembler.java 2001/11/19 19:17:00 1.3
--- NewAssembler.java 2001/11/20 12:17:49 1.4
***************
*** 12,19 ****
+ e.g. A0... this will probably need going over line by line.
- check disp(rX) handling
! - implement the back-patching required for a single pass assembler (or hook up Preprocessor)
- write .align, .byte, .double, .float, .long, .llong, .quad (?), .set (?), .short, .space, .string, .vbyte (?)
- hook it all up to the gui and test
! - remove old assembler stuff that's no longer used (Assembler, Assembling prefs, PowerPCAssemblingPrefs, Preprocessor (?)
- document (inc release notes?)
- release!
--- 12,19 ----
+ e.g. A0... this will probably need going over line by line.
- check disp(rX) handling
! + implement the back-patching required for a single pass assembler (or hook up Preprocessor)
- write .align, .byte, .double, .float, .long, .llong, .quad (?), .set (?), .short, .space, .string, .vbyte (?)
- hook it all up to the gui and test
! - remove old assembler stuff that's no longer used (Assembler, Assembling prefs, Glue, PowerPCAssemblingPrefs, Preprocessor (?)
- document (inc release notes?)
- release!
***************
*** 23,26 ****
--- 23,28 ----
static final String LONG=".long", BYTE=".byte", ALIGN=".align", SPACE=".space", SHORT=".short";
static final String[] directives={LONG, BYTE, ALIGN, SPACE, SHORT};
+ /** Warning levels.*/
+ static final int IGNORE=0, WARN=1, ERROR=2;
InstructionSet is;
***************
*** 30,35 ****
int currentAddress;
Map labelTable;
- /** A store of unassembled lines, needed for back patching.*/
Parser parser;
public NewAssembler(InstructionSet is)
--- 32,37 ----
int currentAddress;
Map labelTable;
Parser parser;
+ StringBuffer warnings;
public NewAssembler(InstructionSet is)
***************
*** 44,47 ****
--- 46,50 ----
instructions.put(t.mnemonic, t);
}
+ warnings=new StringBuffer();
}
***************
*** 101,104 ****
--- 104,130 ----
}
+ void warn(int option, String message) throws OperandFormatException
+ {
+ if (option==1)
+ {
+ warnings.append(message).append(" at line ").append(currentLineNum).append(".\n");
+ }
+ else if (option==2)
+ {
+ throw new OperandFormatException(message + " at line " + currentLineNum+".");
+ }
+ // default: ignore
+ }
+
+ public boolean hasWarnings()
+ {
+ return warnings.length()!=0;
+ }
+
+ public String getWarnings()
+ {
+ return warnings.toString();
+ }
+
/** allow differentiating by both mnemonic and num operands
Bug: change to offer different versions of it depending on number of operands.
***************
*** 171,175 ****
if (line.getMnemonic()==null)
{
! return; // BUG: ugly
}
--- 197,201 ----
if (line.getMnemonic()==null)
{
! return;
}
***************
*** 285,293 ****
}
- /** BUG: doesn't handle forward ref patching yet.*/
public byte[] assemble(String s, Map labels) throws AssemblerException//, IOException
{
currentLineNum=0;
currentAddress=0;
labelTable=labels;
List incompletes=new ArrayList(100);
--- 311,319 ----
}
public byte[] assemble(String s, Map labels) throws AssemblerException//, IOException
{
currentLineNum=0;
currentAddress=0;
+ warnings.setLength(0);
labelTable=labels;
List incompletes=new ArrayList(100);
***************
*** 295,303 ****
DataOutputStream output=new DataOutputStream(buffy);
parser=new Parser(s);
! // set up for while loop
! Line line=parser.parse();
! currentLineNum++;
try
{
while (line!=null)
{
--- 321,330 ----
DataOutputStream output=new DataOutputStream(buffy);
parser=new Parser(s);
!
try
{
+ // set up for while loop
+ Line line=parser.parse();
+ currentLineNum++;
while (line!=null)
{
***************
*** 335,340 ****
}
! /** Test function.*/
! public static void main(String[] args) throws Exception
{
if (args.length!=1)
--- 362,367 ----
}
! /* Test function.*/
! /*public static void main(String[] args) throws Exception
{
if (args.length!=1)
***************
*** 362,365 ****
// System.out.println(asm.lines.get(i).toString());
//}
! }
}
--- 389,392 ----
// System.out.println(asm.lines.get(i).toString());
//}
! }*/
}
|
|
From: Nigel P. <nph...@us...> - 2001-11-20 12:06:38
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv32739/base
Modified Files:
InstructionEncoder.java
Log Message:
Design note.
Index: InstructionEncoder.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/InstructionEncoder.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** InstructionEncoder.java 2001/11/19 16:17:49 1.2
--- InstructionEncoder.java 2001/11/20 12:06:35 1.3
***************
*** 2,6 ****
/** This interface is implemented by platform-specific classes which determine the encoding of the
! field values as taken from the source file by the assembler and specified by the InstructionSet data.*/
public interface InstructionEncoder
{
--- 2,8 ----
/** This interface is implemented by platform-specific classes which determine the encoding of the
! field values as taken from the source file by the assembler and specified by the InstructionSet data.
! BUG: this would be better as an abstract method of the assembler class, requiring instruction set specific
! assembler subclasses?*/
public interface InstructionEncoder
{
|
|
From: Nigel P. <nph...@us...> - 2001-11-20 12:03:00
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv32038/base
Modified Files:
Disassembler.java
Log Message:
Minor tidying.
Index: Disassembler.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/Disassembler.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -r1.18 -r1.19
*** Disassembler.java 2001/11/10 10:44:00 1.18
--- Disassembler.java 2001/11/20 12:02:58 1.19
***************
*** 502,513 ****
{
int primary=PowerPCUtils.extractPrimary(opcode);
-
int a, b, d, simm, uimm, crfd;
-
switch(primary)
{
//case 2:
// tdi
- // BUG: unimplemented
//break;
--- 502,510 ----
|
|
From: Nigel P. <nph...@us...> - 2001-11-20 12:01:20
|
Update of /cvsroot/exspiminator/exspiminator/docs In directory usw-pr-cvs1:/tmp/cvs-serv31710/docs Modified Files: release.html Log Message: Bring up to date. Index: release.html =================================================================== RCS file: /cvsroot/exspiminator/exspiminator/docs/release.html,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** release.html 2001/11/19 16:17:49 1.20 --- release.html 2001/11/20 12:01:17 1.21 *************** *** 1,10 **** <html> <head> ! <title>Exspiminator v0.4 release notes</title> </head> <body> ! <h1>Exspiminator v0.4 release notes</h1> ! <p>These are the release notes for Exspiminator version 0.4 (alpha). Exspiminator is a PowerPC simulator, assembler, and disassembler. It is currently in development and lacks many features. --- 1,10 ---- <html> <head> ! <title>Exspiminator v0.5 release notes</title> </head> <body> ! <h1>Exspiminator v0.5 release notes</h1> ! <p>These are the release notes for Exspiminator version 0.5 (alpha). Exspiminator is a PowerPC simulator, assembler, and disassembler. It is currently in development and lacks many features. *************** *** 20,23 **** --- 20,26 ---- <ul> <li>Added byte reverse loads and stores + <li>Rewrote old two-pass assembler as a single pass assembler + <li>Tightened up type checking + <li>Added some assembler directives. </ul> |
|
From: Nigel P. <nph...@us...> - 2001-11-20 12:00:13
|
Update of /cvsroot/exspiminator/exspiminator/docs
In directory usw-pr-cvs1:/tmp/cvs-serv31425/docs
Modified Files:
tutorial.html
Log Message:
Document new assembler directives.
Index: tutorial.html
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/docs/tutorial.html,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** tutorial.html 2001/11/19 16:17:49 1.6
--- tutorial.html 2001/11/20 12:00:10 1.7
***************
*** 6,10 ****
<h1>Exspiminator tutorial</h1>
! <p>This is a tutorial on using the Exspiminator version 0.4; a (currently incomplete) PowerPC <A HREF="asm-tutorial.html">assembly language tutorial</A> is also provided.
<h2>What's what</h2>
--- 6,10 ----
<h1>Exspiminator tutorial</h1>
! <p>This is a tutorial on using the Exspiminator version 0.5; a (currently incomplete) PowerPC <A HREF="asm-tutorial.html">assembly language tutorial</A> is also provided.
<h2>What's what</h2>
***************
*** 27,32 ****
<p>The assembler is very simple and does not include all the features a production quality assembler would.
! In particular it does not support user-defined macros, assemble-time arithmetic, or assembler directives. For the basic features, read the source files given in the samples folder. Read the <A HREF="release.html">release notes</A> for a full list of supported instructions, read the <A HREF="asm-tutorial.html">assembly tutorial</A> for an introduction to the lanuage, and refer to the <A HREF="bibliography.html">bibliography</A> for links to PowerPC assembly language reference works.
<h3>IO and the simulated program</h3>
--- 27,45 ----
<p>The assembler is very simple and does not include all the features a production quality assembler would.
! In particular it does not support user-defined macros, assemble-time arithmetic, or many assembler directives. For the basic features, read the source files given in the samples folder. Read the <A HREF="release.html">release notes</A> for a full list of supported instructions, read the <A HREF="asm-tutorial.html">assembly tutorial</A> for an introduction to the lanuage, and refer to the <A HREF="bibliography.html">bibliography</A> for links to PowerPC assembly language reference works.
+ <h3>Assembler directives</h3>
+
+ <p>Support for assembler directives is modelled (loosely) on IBM's AIX assembler. Currently supported:
+ <p>
+ <table border="1">
+ <tr><th>Directive<th>Function
+ <tr><td><code>.align <em>N</em></code><td>Aligns the current location counter (padding with zeros) until reaching a boundary given by <em>N</em>: 0 indicates byte alignment, 1 is halfword alignment, 2 is word alignment, and 3 is double word alignment.
+ <tr><td><code>.byte <em>N1, N2, [...] Nn</em></code><td>Stores the least significant byte of the given value(s) into the object code.
+ <tr><td><code>.long <em>N1, N2, [...] Nn</em></code><td>Stores the value(s) into the object code.
+ <tr><td><code>.short <em>N1, N2, [...] Nn</em></code><td>Stores the least significant half word of the given value(s) into the object code.
+ <tr><td><code>.space <em>N</em></code><td>Sets aside space in the object code by inserting <em>N</em> bytes of value 0.
+ </table>
+
<h3>IO and the simulated program</h3>
***************
*** 44,51 ****
read:
li r3, 0 # address of string to prompt user, or 0 for none
! li r4, buffy # address of buffer in which to store the input
! li r5, 20 # the length of the buffer, in bytes
! li r0, 2 # select input
! sc
</pre>
--- 57,64 ----
read:
li r3, 0 # address of string to prompt user, or 0 for none
! li r4, buffy # address of buffer in which to store the input
! li r5, 20 # the length of the buffer, in bytes
! li r0, 2 # select input
! sc
</pre>
|
|
From: Nigel P. <nph...@us...> - 2001-11-20 11:59:02
|
Update of /cvsroot/exspiminator/exspiminator/gui
In directory usw-pr-cvs1:/tmp/cvs-serv31158/gui
Modified Files:
GUI.java
Log Message:
Tidy up and produce user notification on IO error.
Index: GUI.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/gui/GUI.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -r1.22 -r1.23
*** GUI.java 2001/11/19 16:17:49 1.22
--- GUI.java 2001/11/20 11:58:59 1.23
***************
*** 400,441 ****
in.read(source, 0, (int) fileLength);
! /** BUG: temporarily use preprocessor to produce label table, until we get
! back patching working.*/
! //Preprocessor pp=new Preprocessor(
! // SimplifiedPowerPCInstructionSet.getInstructionSet());
! //String data=pp.preprocess(new String(source));
! //if (data==null)
! //{
! // JOptionPane.showMessageDialog(frame,
! // pp.getErrorMessage(),
! // "Preprocessing failed",
! // JOptionPane.ERROR_MESSAGE);
! //}
! //else
! //{
! //Assembler asm=new Assembler(
! NewAssembler asm=new NewAssembler(
! SimplifiedPowerPCInstructionSet.getInstructionSet());
! //asm.setLabelTable(pp.getLabelTable());
//System.err.println(pp.getLabelTable().toString());
! try
{
- byte[] code=asm.assemble(new String(source));
- //(new String(data), pp.getLabelTable());
- MemoryModel m=new MemoryModel(code);
- setModels(new PowerPC(m), m);
- }
- catch (AssemblerException aEx)
- {
JOptionPane.showMessageDialog(frame,
! aEx.getMessage(),
! "Assembling failed",
! JOptionPane.ERROR_MESSAGE);
}
! //}
}
catch (IOException ex)
{
! //BUG: nice error handling! :-)
}
finally
--- 400,433 ----
in.read(source, 0, (int) fileLength);
! NewAssembler asm=new NewAssembler(
! SimplifiedPowerPCInstructionSet.getInstructionSet());
//System.err.println(pp.getLabelTable().toString());
! try
! {
! byte[] code=asm.assemble(new String(source));
! //(new String(data), pp.getLabelTable());
! if (asm.hasWarnings())
{
JOptionPane.showMessageDialog(frame,
! asm.getWarnings(),
! "Warning",
! JOptionPane.WARNING_MESSAGE);
}
!
! MemoryModel m=new MemoryModel(code);
! setModels(new PowerPC(m), m);
! }
! catch (AssemblerException aEx)
! {
! JOptionPane.showMessageDialog(frame,
! aEx.getMessage(),
! "Assembling failed",
! JOptionPane.ERROR_MESSAGE);
! }
}
catch (IOException ex)
{
! JOptionPane.showMessageDialog(frame, "An error occured:" + ex.getMessage(),
! "IO Error", JOptionPane.ERROR_MESSAGE);
}
finally
|
|
From: Nigel P. <nph...@us...> - 2001-11-19 19:18:14
|
Update of /cvsroot/exspiminator/exspiminator/samples In directory usw-pr-cvs1:/tmp/cvs-serv20031/samples Modified Files: sort.txt Log Message: Use newly-implemented .long directive. Index: sort.txt =================================================================== RCS file: /cvsroot/exspiminator/exspiminator/samples/sort.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** sort.txt 2001/11/19 16:17:49 1.5 --- sort.txt 2001/11/19 19:18:11 1.6 *************** *** 28,44 **** blr ! ! ! buffy: ! # .word 1 2 3 4 5 6 7 8 9 0 # A ten word buffer ! ! ori r0, r0, 10 ! ori r0, r0, 1 ! ori r0, r0, 8 ! ori r0, r0, 3 ! ori r0, r0, 6 ! ori r0, r0, 5 ! ori r0, r0, 4 ! ori r0, r0, 7 ! ori r0, r0, 2 ! ori r0, r0, 9 \ No newline at end of file --- 28,31 ---- blr ! buffy: .long 10, 1, 8, 3, 6 # data to be sorted ! .long 5, 4, 7, 2, 9 \ No newline at end of file |
|
From: Nigel P. <nph...@us...> - 2001-11-19 19:17:04
|
Update of /cvsroot/exspiminator/exspiminator/base
In directory usw-pr-cvs1:/tmp/cvs-serv19677/base
Modified Files:
NewAssembler.java PowerPCInstructionEncoder.java
Log Message:
Move some generic functionality from platform specific to platform netural areas (PPCInstructionEncoder to NewAssembler). Implement some assembler directives.
Index: NewAssembler.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/NewAssembler.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** NewAssembler.java 2001/11/19 16:17:49 1.2
--- NewAssembler.java 2001/11/19 19:17:00 1.3
***************
*** 21,24 ****
--- 21,27 ----
public class NewAssembler
{
+ static final String LONG=".long", BYTE=".byte", ALIGN=".align", SPACE=".space", SHORT=".short";
+ static final String[] directives={LONG, BYTE, ALIGN, SPACE, SHORT};
+
InstructionSet is;
Map instructions;
***************
*** 58,63 ****
}
! /** allow differentiating by both mnemonic and num operands
Bug: change to offer different versions of it depending on number of operands.
May involve name mangling... or not: could do it properly and make a comparitor
--- 61,105 ----
}
! /** Modify to allow alises at some point?*/
! int parseInt(String s) throws OperandFormatException
! {
! try
! {
! return Integer.parseInt(s);
! }
! catch (NumberFormatException ex)
! {
! throw new OperandFormatException("Integer expected (found '" + s
! + "' at line " + getCurrentLineNum() + ".");
! }
! }
!
! /** This performs the label substitution or literal parsing for branch targets.
! Also used to allow things like <code>li rA, label</code> and <code>la rA, label(rB)</code>.
! BUG: remember we'll have to deal with aliases too at some point.*/
! int resolveLabelOrInt(String target) throws OperandFormatException
! {
! int result;
! Integer i1=resolveLabel(target);
! if (i1!=null)
! {
! result=i1.intValue();
! }
! else
! {
! try
! {
! // fall back to parseInt
! result=Integer.parseInt(target);
! }
! catch (NumberFormatException ex)
! {
! throw new UnknownSymbolException();
! }
! }
! return result;
! }
+ /** allow differentiating by both mnemonic and num operands
Bug: change to offer different versions of it depending on number of operands.
May involve name mangling... or not: could do it properly and make a comparitor
***************
*** 84,87 ****
--- 126,143 ----
}
+ /** Returns the string matching the given string iff it is contained in the directives array.
+ Just uses a linear search: the list of possible directives is short.*/
+ String lookupDirective(String directive)
+ {
+ for (int i=0; i<directives.length; i++)
+ {
+ if (directive.equals(directives[i]))
+ {
+ return directives[i];
+ }
+ }
+ return null;
+ }
+
/** Returns true if the string is empty, the first character is a digit, or it's
a mnemonic in the current instruction set (since that would mess up our crappy address
***************
*** 94,100 ****
|| is.isLegalMnemonic(s) || s.indexOf(":")!=-1;
}
-
- /** Pass a null value for incompletes when backpatching.
@param incompletes A list to which to add a list of AssemblyLines producing an UnknownSymbolException.
If this vlaue if null, a new AssemblerException will be thrown.*/
--- 150,155 ----
|| is.isLegalMnemonic(s) || s.indexOf(":")!=-1;
}
+ /** Pass a null value for incompletes when backpatching.
@param incompletes A list to which to add a list of AssemblyLines producing an UnknownSymbolException.
If this vlaue if null, a new AssemblerException will be thrown.*/
***************
*** 141,145 ****
else
{
! throw new AssemblerException("Unknown symbol at line " + lineNum);
}
}
--- 196,200 ----
else
{
! throw new AssemblerException("Unknown operand symbol at line " + lineNum);
}
}
***************
*** 149,161 ****
else
{
! /*it=lookupDirective(line.getMnemonic(), line.getNumOperands());
! if (it==null)
{
! */ throw new AssemblerException("Unknown identifier at line " + lineNum);
! /*}
! else if (it==directive[0])
{
! // handle .long etc??
! }*/
}
}
--- 204,280 ----
else
{
! String directive=lookupDirective(line.getMnemonic());
! if (directive==null)
! {
! throw new AssemblerException("Unknown symbol at line " + lineNum);
! }
! else if (directive==LONG)
! {
! for (int i=0; i<line.getNumOperands(); i++)
! {
! output.writeInt(parseInt(line.getOperand(i)));
! currentAddress+=4;
! }
! }
! else if (directive==BYTE)
! {
! for (int i=0; i<line.getNumOperands(); i++)
! {
! output.writeByte(parseInt(line.getOperand(i)));
! currentAddress+=1;
! }
! }
! else if (directive==ALIGN)
! {
! if (line.getNumOperands()!=1)
! {
! throw new AssemblerException("Wrong number of operands ("
! + line.getNumOperands() + " found, 1 expected) at line "
! + currentLineNum);
! }
! int operand=parseInt(line.getOperand(0));
! if (operand<0 || operand>3)
! {
! throw new AssemblerException("Invalid alignmnent operand at line "
! + currentLineNum);
! }
! int boundary=1<<operand;
! int rem=currentAddress % boundary;
! if (rem!=0)
! {
! int pad=boundary-rem;
! while (pad>0)
! {
! output.writeByte(0);
! currentAddress++;
! pad--;
! }
! }
! }
! else if (directive==SPACE)
{
! if (line.getNumOperands()!=1)
! {
! throw new AssemblerException("Wrong number of operands ("
! + line.getNumOperands() + " found, 1 expected) at line "
! + currentLineNum);
! }
! int operand=parseInt(line.getOperand(0));
! while (operand>0)
! {
! output.writeByte(0);
! currentAddress++;
! operand--;
! }
! }
! else if (directive==SHORT)
{
! for (int i=0; i<line.getNumOperands(); i++)
! {
! output.writeShort(parseInt(line.getOperand(i)));
! currentAddress+=2;
! }
! }
! // else we don't handle it yet
}
}
Index: PowerPCInstructionEncoder.java
===================================================================
RCS file: /cvsroot/exspiminator/exspiminator/base/PowerPCInstructionEncoder.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** PowerPCInstructionEncoder.java 2001/11/19 16:17:49 1.2
--- PowerPCInstructionEncoder.java 2001/11/19 19:17:00 1.3
***************
*** 44,87 ****
}
- int parseInt(String s) throws OperandFormatException
- {
- try
- {
- return Integer.parseInt(s);
- }
- catch (NumberFormatException ex)
- {
- throw new OperandFormatException("Integer expected (found '" + s
- + "' at line " + asm.getCurrentLineNum() + ".");
- }
- }
-
- /** This performs the label substitution or literal parsing for branch targets.
- Also used to allow things like <code>li rA, label</code> and <code>la rA, label(rB)</code>.
- BUG: remember we'll have to deal with aliases too at some point.
- BUG: this functionality is quite generic and therefore better suited to the Assembler?*/
- int resolveLabelOrInt(String target) throws OperandFormatException
- {
- int result;
- Integer i1=asm.resolveLabel(target);
- if (i1!=null)
- {
- result=i1.intValue();
- }
- else
- {
- try
- {
- // fall back to parseInt
- result=Integer.parseInt(target);
- }
- catch (NumberFormatException ex)
- {
- throw new UnknownSymbolException();
- }
- }
- return result;
- }
-
int parseGpr(String s) throws OperandFormatException
{
--- 44,47 ----
***************
*** 89,98 ****
if (s.startsWith(gprPrefix))
{
! result=parseInt(s.substring(gprPrefix.length()));
}
else
{
warn(forceGprPrefix, "Missing GPR prefix");
! result=parseInt(s);
}
if (result<0 || result>31)
--- 49,58 ----
if (s.startsWith(gprPrefix))
{
! result=asm.parseInt(s.substring(gprPrefix.length()));
}
else
{
warn(forceGprPrefix, "Missing GPR prefix");
! result=asm.parseInt(s);
}
if (result<0 || result>31)
***************
*** 145,154 ****
if (s.startsWith(crbPrefix))
{
! result=parseInt(s.substring(crbPrefix.length()));
}
else
{
warn(forceCrbPrefix, "Missing CRB prefix (" + crbPrefix + ")");
! result=parseInt(s);
}
if (result<0 || result>31)
--- 105,114 ----
if (s.startsWith(crbPrefix))
{
! result=asm.parseInt(s.substring(crbPrefix.length()));
}
else
{
warn(forceCrbPrefix, "Missing CRB prefix (" + crbPrefix + ")");
! result=asm.parseInt(s);
}
if (result<0 || result>31)
***************
*** 191,195 ****
case PowerPCInstructionSet.BD:
! operand=resolveLabelOrInt(rawOperand);
if ((operand & 3) !=0)
{
--- 151,155 ----
case PowerPCInstructionSet.BD:
! operand=asm.resolveLabelOrInt(rawOperand);
if ((operand & 3) !=0)
{
***************
*** 217,226 ****
if (rawOperand.startsWith(crfPrefix))
{
! operand=parseInt(rawOperand.substring(crfPrefix.length()));
}
else
{
warn(forceCrfPrefix, "Missing CRF prefix");
! operand=parseInt(rawOperand);
}
if (operand>=0 && operand<=7)
--- 177,186 ----
if (rawOperand.startsWith(crfPrefix))
{
! operand=asm.parseInt(rawOperand.substring(crfPrefix.length()));
}
else
{
warn(forceCrfPrefix, "Missing CRF prefix");
! operand=asm.parseInt(rawOperand);
}
if (operand>=0 && operand<=7)
***************
*** 236,240 ****
case PowerPCInstructionSet.LI:
! operand=resolveLabelOrInt(rawOperand);
if ((operand & 3) !=0)
{
--- 196,200 ----
case PowerPCInstructionSet.LI:
! operand=asm.resolveLabelOrInt(rawOperand);
if ((operand & 3) !=0)
{
***************
*** 259,263 ****
case PowerPCInstructionSet.SIMM:
! operand=resolveLabelOrInt(rawOperand);
if (operand>=Short.MIN_VALUE && operand<=Short.MAX_VALUE)
{
--- 219,223 ----
case PowerPCInstructionSet.SIMM:
! operand=asm.resolveLabelOrInt(rawOperand);
if (operand>=Short.MIN_VALUE && operand<=Short.MAX_VALUE)
{
***************
*** 272,276 ****
case PowerPCInstructionSet.UIMM:
! operand=resolveLabelOrInt(rawOperand);
if (operand>=0 && operand<(1<<16))
{
--- 232,236 ----
case PowerPCInstructionSet.UIMM:
! operand=asm.resolveLabelOrInt(rawOperand);
if (operand>=0 && operand<(1<<16))
{
***************
*** 285,289 ****
case PowerPCInstructionSet.L:
! operand=parseInt(rawOperand);
if (operand==0 || operand==1)
{
--- 245,249 ----
case PowerPCInstructionSet.L:
! operand=asm.parseInt(rawOperand);
if (operand==0 || operand==1)
{
***************
*** 300,304 ****
case PowerPCInstructionSet.MB:
case PowerPCInstructionSet.ME:
! operand=parseInt(rawOperand);
if (operand>=0 && operand<=31)
{
--- 260,264 ----
case PowerPCInstructionSet.MB:
case PowerPCInstructionSet.ME:
! operand=asm.parseInt(rawOperand);
if (operand>=0 && operand<=31)
{
***************
*** 313,317 ****
case PowerPCInstructionSet.SPR:
! operand=parseInt(rawOperand);
if (operand==1 || operand==8 || operand==9)
{
--- 273,277 ----
case PowerPCInstructionSet.SPR:
! operand=asm.parseInt(rawOperand);
if (operand==1 || operand==8 || operand==9)
{
***************
*** 329,333 ****
case PowerPCInstructionSet.CRM:
! operand=parseInt(rawOperand);
if (operand>=0 && operand<=0xFF)
{
--- 289,293 ----
case PowerPCInstructionSet.CRM:
! operand=asm.parseInt(rawOperand);
if (operand>=0 && operand<=0xFF)
{
***************
*** 342,346 ****
case PowerPCInstructionSet.BI:
! operand=parseInt(rawOperand);
if (operand>=0 && operand<=31)
{
--- 302,306 ----
case PowerPCInstructionSet.BI:
! operand=asm.parseInt(rawOperand);
if (operand>=0 && operand<=31)
{
***************
*** 355,359 ****
case PowerPCInstructionSet.BO:
! operand=parseInt(rawOperand);
// BUG: could be more exclusive than this?
if (operand>=0 && operand<=31)
--- 315,319 ----
case PowerPCInstructionSet.BO:
! operand=asm.parseInt(rawOperand);
// BUG: could be more exclusive than this?
if (operand>=0 && operand<=31)
***************
*** 396,400 ****
// overcome warning as r is required for regs etc.
case SimplifiedPowerPCInstructionSet.NEGSIMM:
! operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.SIMM, ""+(-operand));
--- 356,360 ----
// overcome warning as r is required for regs etc.
case SimplifiedPowerPCInstructionSet.NEGSIMM:
! operand=asm.parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.SIMM, ""+(-operand));
***************
*** 426,439 ****
case SimplifiedPowerPCInstructionSet.ME_PLUS_1:
! operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.ME, ""+(operand-1));
case SimplifiedPowerPCInstructionSet.THIRTY_TWO_MINUS_MB:
! operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.MB, ""+(32-operand));
case SimplifiedPowerPCInstructionSet.COMPLETE1:
{
! operand=parseInt(rawOperand);
int n=32-PowerPCUtils.extractMB(opcode);
return insertField(opcode, PowerPCInstructionSet.SH, ""+(operand+n));
--- 386,399 ----
case SimplifiedPowerPCInstructionSet.ME_PLUS_1:
! operand=asm.parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.ME, ""+(operand-1));
case SimplifiedPowerPCInstructionSet.THIRTY_TWO_MINUS_MB:
! operand=asm.parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.MB, ""+(32-operand));
case SimplifiedPowerPCInstructionSet.COMPLETE1:
{
! operand=asm.parseInt(rawOperand);
int n=32-PowerPCUtils.extractMB(opcode);
return insertField(opcode, PowerPCInstructionSet.SH, ""+(operand+n));
***************
*** 441,450 ****
case SimplifiedPowerPCInstructionSet.TEMP_ME:
! operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.ME, ""+operand);
case SimplifiedPowerPCInstructionSet.COMPLETE2:
{
! operand=parseInt(rawOperand);
opcode=insertField(opcode, PowerPCInstructionSet.MB, ""+operand);
opcode=insertField(opcode, PowerPCInstructionSet.SH, ""+(32-operand));
--- 401,410 ----
case SimplifiedPowerPCInstructionSet.TEMP_ME:
! operand=asm.parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.ME, ""+operand);
case SimplifiedPowerPCInstructionSet.COMPLETE2:
{
! operand=asm.parseInt(rawOperand);
opcode=insertField(opcode, PowerPCInstructionSet.MB, ""+operand);
opcode=insertField(opcode, PowerPCInstructionSet.SH, ""+(32-operand));
***************
*** 456,460 ****
case SimplifiedPowerPCInstructionSet.COMPLETE3:
{
! operand=parseInt(rawOperand);
opcode=insertField(opcode, PowerPCInstructionSet.MB, ""+operand);
int n=PowerPCUtils.extractME(opcode);
--- 416,420 ----
case SimplifiedPowerPCInstructionSet.COMPLETE3:
{
! operand=asm.parseInt(rawOperand);
opcode=insertField(opcode, PowerPCInstructionSet.MB, ""+operand);
int n=PowerPCUtils.extractME(opcode);
***************
*** 465,473 ****
case SimplifiedPowerPCInstructionSet.THIRTY_TWO_MINUS_SH:
! operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.SH, ""+(32-operand));
case SimplifiedPowerPCInstructionSet.SH_AND_31_MINUS_ME:
! operand=parseInt(rawOperand);
return insertField(
insertField(opcode, PowerPCInstructionSet.SH, ""+operand),
--- 425,433 ----
case SimplifiedPowerPCInstructionSet.THIRTY_TWO_MINUS_SH:
! operand=asm.parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.SH, ""+(32-operand));
case SimplifiedPowerPCInstructionSet.SH_AND_31_MINUS_ME:
! operand=asm.parseInt(rawOperand);
return insertField(
insertField(opcode, PowerPCInstructionSet.SH, ""+operand),
***************
*** 475,479 ****
case SimplifiedPowerPCInstructionSet.MB_AND_32_MINUS_SH:
! operand=parseInt(rawOperand);
return insertField(
insertField(opcode, PowerPCInstructionSet.MB, ""+operand),
--- 435,439 ----
case SimplifiedPowerPCInstructionSet.MB_AND_32_MINUS_SH:
! operand=asm.parseInt(rawOperand);
return insertField(
insertField(opcode, PowerPCInstructionSet.MB, ""+operand),
***************
*** 481,490 ****
case SimplifiedPowerPCInstructionSet.THIRTY_ONE_MINUS_ME:
! operand=parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.ME, ""+(31-operand));
case SimplifiedPowerPCInstructionSet.COMPLETE4:
{
! operand=parseInt(rawOperand);
opcode=insertField(opcode, PowerPCInstructionSet.SH, ""+operand);
int b=PowerPCUtils.extractME(opcode);
--- 441,450 ----
case SimplifiedPowerPCInstructionSet.THIRTY_ONE_MINUS_ME:
! operand=asm.parseInt(rawOperand);
return insertField(opcode, PowerPCInstructionSet.ME, ""+(31-operand));
case SimplifiedPowerPCInstructionSet.COMPLETE4:
{
! operand=asm.parseInt(rawOperand);
opcode=insertField(opcode, PowerPCInstructionSet.SH, ""+operand);
int b=PowerPCUtils.extractME(opcode);
|