Implement setcc instructions#184
This commit is contained in:
Simon Fortier 2019-01-23 19:23:22 -05:00 committed by GitHub
commit 75410cc0db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 1978 additions and 27 deletions

View File

@ -544,7 +544,6 @@ public class Assembler {
if (instructionSet.get(mnemonic) == null) {
throw new InvalidMnemonicException(mnemonic, currentLine);
}
//Check operands and encode instruction

View File

@ -1,7 +1,6 @@
package net.simon987.server.assembly;
import net.simon987.server.assembly.instruction.*;
import net.simon987.server.logging.LogManager;
import java.util.HashMap;
import java.util.Map;
@ -51,9 +50,11 @@ public class DefaultInstructionSet implements InstructionSet {
add(new SarInstruction());
add(new IncInstruction());
add(new DecInstruction());
add(new SetccInstruction());
// aliases
add(new SalInstruction());
add(new SetzInstruction());
}
/**
@ -107,7 +108,7 @@ public class DefaultInstructionSet implements InstructionSet {
public void add(Instruction instruction) {
Instruction aliasedInstruction = instructionMap.get(instruction.getOpCode());
if (aliasedInstruction != null) {
aliasesMap.put(instruction.getMnemonic(), aliasedInstruction);
aliasesMap.put(instruction.getMnemonic(), instruction);
} else {
instructionMap.put(instruction.getOpCode(), instruction);
}

View File

@ -1,6 +1,6 @@
package net.simon987.server.assembly;
import net.simon987.server.assembly.exception.AssemblyException;
import net.simon987.server.assembly.exception.IllegalOperandException;
import java.io.ByteArrayOutputStream;
@ -102,7 +102,7 @@ public abstract class Instruction {
* @param o2 Source operand
* @return true if valid
*/
private static boolean operandsValid(Operand o1, Operand o2) throws IllegalOperandException {
public boolean operandsValid(Operand o1, Operand o2) {
return o1.getType() != OperandType.IMMEDIATE16;
}
@ -112,7 +112,7 @@ public abstract class Instruction {
* @param o1 source operand
* @return true if the specified operand can be used with this instruction
*/
private static boolean operandValid(Operand o1) {
public boolean operandValid(Operand o1) {
return true;
}
@ -124,7 +124,7 @@ public abstract class Instruction {
return false;
}
String getMnemonic() {
public String getMnemonic() {
return mnemonic;
}
@ -133,7 +133,7 @@ public abstract class Instruction {
*
* @param out encoded bytes will be written here
*/
public void encode(ByteArrayOutputStream out, int currentLine) throws IllegalOperandException {
public void encode(ByteArrayOutputStream out, int currentLine) throws AssemblyException {
if (!noOperandsValid()) {
throw new IllegalOperandException("This instruction must have operand(s)!", currentLine);
@ -148,7 +148,7 @@ public abstract class Instruction {
}
public void encode(ByteArrayOutputStream out, Operand o1, Operand o2, int currentLine)
throws IllegalOperandException {
throws AssemblyException {
MachineCode code = new MachineCode();
code.writeOpcode(opCode);
@ -183,7 +183,7 @@ public abstract class Instruction {
}
public void encode(ByteArrayOutputStream out, Operand o1, int currentLine)
throws IllegalOperandException {
throws AssemblyException {
MachineCode code = new MachineCode();
code.writeOpcode(opCode);
@ -208,7 +208,7 @@ public abstract class Instruction {
}
}
int getOpCode() {
public int getOpCode() {
return opCode;
}
}

View File

@ -10,7 +10,7 @@ import java.util.ArrayList;
* Represents an encoded instruction. this class is used to easily
* write to an 16bit value.
*/
class MachineCode {
public class MachineCode {
/**
* Value of the initial 2-byte instruction
@ -27,7 +27,7 @@ class MachineCode {
*
* @param opCode signed 6-bit integer (value 0-63)
*/
void writeOpcode(int opCode) {
public void writeOpcode(int opCode) {
if (opCode < 0 || opCode > 63) {
LogManager.LOGGER.severe("Couldn't write the opCode for instruction :" + opCode);
@ -44,7 +44,7 @@ class MachineCode {
*
* @param src signed 5-bit integer (value 0-31)
*/
void writeSourceOperand(int src) {
public void writeSourceOperand(int src) {
if (src < 0 || src > 31) {
LogManager.LOGGER.severe("Couldn't write the scr operand for instruction :" + src);
@ -62,7 +62,7 @@ class MachineCode {
*
* @param dst signed 5-bit integer (value 0-31)
*/
void writeDestinationOperand(int dst) {
public void writeDestinationOperand(int dst) {
if (dst < 0 || dst > 31) {
LogManager.LOGGER.severe("Couldn't write the dst operand for instruction :" + dst);
} else {
@ -73,14 +73,14 @@ class MachineCode {
}
}
void appendWord(char word) {
public void appendWord(char word) {
additionalWords.add(word);
}
/**
* Get the bytes of the code
*/
byte[] bytes() {
public byte[] bytes() {
ByteArrayOutputStream out = new ByteArrayOutputStream();

View File

@ -10,9 +10,9 @@ import java.util.HashMap;
*/
public class Operand {
static final int IMMEDIATE_VALUE = 0b11111; //1 1111
public static final int IMMEDIATE_VALUE = 0b11111; //1 1111
static final int IMMEDIATE_VALUE_MEM = 0b11110; //1 1110
public static final int IMMEDIATE_VALUE_MEM = 0b11110; //1 1110
/**
* The actual text of the operand (e.g. "[AX]")
@ -36,6 +36,16 @@ public class Operand {
*/
private int data = 0;
public Operand(OperandType type, int value) {
this.type = type;
this.value = value;
}
public Operand(OperandType type, int value, int data) {
this(type, value);
this.data = data;
}
/**
* Create an Operand from text. It assumes that the numerical values that can't be
* parsed are labels that are not defined yet.
@ -252,7 +262,7 @@ public class Operand {
}
}
OperandType getType() {
public OperandType getType() {
return type;
}
@ -260,7 +270,7 @@ public class Operand {
return value;
}
int getData() {
public int getData() {
return data;
}
}

View File

@ -1,13 +1,11 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Instruction;
/**
* Alias of SHL instruction
*/
public class SalInstruction extends Instruction {
public class SalInstruction extends ShlInstruction {
public SalInstruction() {
super("sal", ShlInstruction.OPCODE);
super("sal");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetaInstruction extends SetccInstruction {
public SetaInstruction() {
super("seta");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetaeInstruction extends SetccInstruction {
public SetaeInstruction() {
super("setae");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetbInstruction extends SetccInstruction {
public SetbInstruction() {
super("setb");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetbeInstruction extends SetccInstruction {
public SetbeInstruction() {
super("setbe");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetcInstruction extends SetccInstruction {
public SetcInstruction() {
super("setc");
}
}

View File

@ -0,0 +1,341 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Instruction;
import net.simon987.server.assembly.Status;
import net.simon987.server.assembly.Target;
import net.simon987.server.assembly.Operand;
import net.simon987.server.assembly.OperandType;
import net.simon987.server.assembly.MachineCode;
import net.simon987.server.assembly.exception.AssemblyException;
import net.simon987.server.assembly.exception.IllegalOperandException;
import net.simon987.server.assembly.exception.InvalidMnemonicException;
import java.io.ByteArrayOutputStream;
import java.util.Map;
import java.util.HashMap;
/**
* Implementation of the SETcc family of instructions
* http://www.ousob.com/ng/iapx86/ng22d84.php
*/
public class SetccInstruction extends Instruction {
public static final int OPCODE = 50;
public static final int SETA = 0x01;
public static final int SETAE = 0x02;
public static final int SETBE = 0x03;
public static final int SETB = 0x04;
public static final int SETE = 0x05;
public static final int SETNE = 0x06;
public static final int SETG = 0x07;
public static final int SETGE = 0x08;
public static final int SETLE = 0x09;
public static final int SETL = 0x0A;
public static final int SETO = 0x0B;
public static final int SETNO = 0x0C;
public static final int SETS = 0x0D;
public static final int SETNS = 0x0E;
/**
* Map of mnemonics, stored in mnemonic : family op code
* This map includes aliases
*/
private static final Map<String, Character> mnemonicFamilyOpCodeMap = new HashMap<>(26);
static {
mnemonicFamilyOpCodeMap.put("seta", (char) SETA);
mnemonicFamilyOpCodeMap.put("setnbe", (char) SETA);
mnemonicFamilyOpCodeMap.put("setae", (char) SETAE);
mnemonicFamilyOpCodeMap.put("setnb", (char) SETAE);
mnemonicFamilyOpCodeMap.put("setnc", (char) SETAE);
mnemonicFamilyOpCodeMap.put("setbe", (char) SETBE);
mnemonicFamilyOpCodeMap.put("setna", (char) SETBE);
mnemonicFamilyOpCodeMap.put("setb", (char) SETB);
mnemonicFamilyOpCodeMap.put("setc", (char) SETB);
mnemonicFamilyOpCodeMap.put("setnae", (char) SETB);
mnemonicFamilyOpCodeMap.put("sete", (char) SETE);
mnemonicFamilyOpCodeMap.put("setz", (char) SETE);
mnemonicFamilyOpCodeMap.put("setne", (char) SETNE);
mnemonicFamilyOpCodeMap.put("setnz", (char) SETNE);
mnemonicFamilyOpCodeMap.put("setg", (char) SETG);
mnemonicFamilyOpCodeMap.put("setnle", (char) SETG);
mnemonicFamilyOpCodeMap.put("setge", (char) SETGE);
mnemonicFamilyOpCodeMap.put("setnl", (char) SETGE);
mnemonicFamilyOpCodeMap.put("setle", (char) SETLE);
mnemonicFamilyOpCodeMap.put("setng", (char) SETLE);
mnemonicFamilyOpCodeMap.put("setl", (char) SETL);
mnemonicFamilyOpCodeMap.put("setnge", (char) SETL);
mnemonicFamilyOpCodeMap.put("seto", (char) SETO);
mnemonicFamilyOpCodeMap.put("setno", (char) SETNO);
mnemonicFamilyOpCodeMap.put("sets", (char) SETS);
mnemonicFamilyOpCodeMap.put("setns", (char) SETNS);
}
public SetccInstruction() {
super("setcc", OPCODE);
}
public SetccInstruction(String alias) {
super(alias, OPCODE);
}
/**
* The SET instructions set the 16-bit destination to 1 if the
* specified condition is true, otherwise destination is set to 0.
* <p>
* FamilyOpcode Instruction SET to 1 if ... else to 0 Flags
* 0x01 SETA, SETNBE Above, Not Below or Equal CF=0 AND ZF=0
* 0x02 SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0
* 0x03 SETBE, SETNA Below or Equal, Not Above CF=1 OR ZF=1
* 0x04 SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1
* 0x05 SETE, SETZ Equal, Zero ZF=1
* 0x06 SETNE, SETNZ Not Equal, Not Zero ZF=0
* 0x07 SETG, SETNLE Greater, Not Less or Equal SF=OF AND ZF=0
* 0x08 SETGE, SETNL Greater or Equal, Not Less SF=OF
* 0x09 SETLE, SETNG Less or Equal, Not Greater SF<>OF OR ZF=1
* 0x0A SETL, SETNGE Less, Not Greater or Equal SF<>OF
* 0x0B SETO Overflow OF=1
* 0x0C SETNO No Overflow OF=0
* 0x0D SETS Sign (negative) SF=1
* 0x0E SETNS No Sign (positive) SF=0
*/
private static Status setcc(Target dst, int dstIndex, int familyOpCode, Status status) {
switch (familyOpCode) {
case SETA:
return seta(dst, dstIndex, status);
case SETAE:
return setae(dst, dstIndex, status);
case SETBE:
return setbe(dst, dstIndex, status);
case SETB:
return setb(dst, dstIndex, status);
case SETE:
return sete(dst, dstIndex, status);
case SETNE:
return setne(dst, dstIndex, status);
case SETG:
return setg(dst, dstIndex, status);
case SETGE:
return setge(dst, dstIndex, status);
case SETLE:
return setle(dst, dstIndex, status);
case SETL:
return setl(dst, dstIndex, status);
case SETO:
return seto(dst, dstIndex, status);
case SETNO:
return setno(dst, dstIndex, status);
case SETS:
return sets(dst, dstIndex, status);
case SETNS:
return setns(dst, dstIndex, status);
default:
return status;
}
}
/**
* Target can be a memory location or register adressable by dst[dstIndex]
* FamilyOpcode is the value encoded in the source operand as immidiate value
* it will be used to determince what specfic SETcc operation should be execute
*/
@Override
public Status execute(Target dst, int dstIndex, int familyOpCode, Status status) {
return setcc(dst, dstIndex, familyOpCode, status);
}
/**
* This instruction can never be encoded with 2 operands since one word is reserved for its family op code encoding
*/
@Override
public boolean operandsValid(Operand o1, Operand o2) {
return false;
}
@Override
public boolean operandValid(Operand o1) {
return o1.getType() != OperandType.IMMEDIATE16;
}
/**
* Encodes the instruction. Writes the result in the outputStream.
* Needs one operand of OperandType.REGISTER or OperandType.MEMORY_REG16
*
* @param out encoded bytes will be written here
*/
@Override
public void encode(ByteArrayOutputStream out, Operand o1, int currentLine) throws AssemblyException {
String mnemonic = getMnemonic().toLowerCase();
Character familyOpCode = mnemonicFamilyOpCodeMap.get(mnemonic);
// This will catch the off case that someone uses the mnemonic 'setcc'
// as far as the assembler knows this is a valid instruction, but we know it isn't
if (familyOpCode == null) {
throw new InvalidMnemonicException(getMnemonic(), currentLine);
}
if (!operandValid(o1)) {
throw new IllegalOperandException("Illegal operand combination: " + o1.getType() + " (none)", currentLine);
}
MachineCode code = new MachineCode();
code.writeOpcode(getOpCode());
code.writeSourceOperand(Operand.IMMEDIATE_VALUE);
code.appendWord(familyOpCode);
if (o1.getType() == OperandType.REGISTER16 || o1.getType() == OperandType.MEMORY_REG16) {
code.writeDestinationOperand(o1.getValue());
} else {
code.writeDestinationOperand(o1.getValue());
code.appendWord((char) o1.getData());
}
for (byte b : code.bytes()) {
out.write(b);
}
}
/**
* SETA, SETNBE Above, Not Below or Equal CF=0 AND ZF=0
*/
private static Status seta(Target dst, int dstIndex, Status status) {
boolean condition = !status.isCarryFlag() && !status.isZeroFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0
*/
private static Status setae(Target dst, int dstIndex, Status status) {
boolean condition = !status.isCarryFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETBE, SETNA Below or Equal, Not Above CF=1 OR ZF=1
*/
private static Status setbe(Target dst, int dstIndex, Status status) {
boolean condition = status.isCarryFlag() || status.isZeroFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1
*/
private static Status setb(Target dst, int dstIndex, Status status) {
boolean condition = status.isCarryFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETE, SETZ Equal, Zero ZF=1
*/
private static Status sete(Target dst, int dstIndex, Status status) {
boolean condition = status.isZeroFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETNE, SETNZ Not Equal, Not Zero ZF=0
*/
private static Status setne(Target dst, int dstIndex, Status status) {
boolean condition = !status.isZeroFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETG, SETNLE Greater, Not Less or Equal SF=OF AND ZF=0
*/
private static Status setg(Target dst, int dstIndex, Status status) {
boolean condition = (status.isSignFlag() == status.isOverflowFlag()) && !status.isZeroFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETGE, SETNL Greater or Equal, Not Less SF=OF
*/
private static Status setge(Target dst, int dstIndex, Status status) {
boolean condition = status.isSignFlag() == status.isOverflowFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETLE, SETNG Less or Equal, Not Greater SF<>OF OR ZF=1
*/
private static Status setle(Target dst, int dstIndex, Status status) {
boolean condition = (status.isSignFlag() != status.isOverflowFlag()) || status.isZeroFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETL, SETNGE Less, Not Greater or Equal SF<>OF
*/
private static Status setl(Target dst, int dstIndex, Status status) {
boolean condition = status.isSignFlag() != status.isOverflowFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETO Overflow OF=1
*/
private static Status seto(Target dst, int dstIndex, Status status) {
boolean condition = status.isOverflowFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETNO No Overflow OF=0
*/
private static Status setno(Target dst, int dstIndex, Status status) {
boolean condition = !status.isOverflowFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETS Sign (negative) SF=1
*/
private static Status sets(Target dst, int dstIndex, Status status) {
boolean condition = status.isSignFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
/**
* SETNS No Sign (positive) SF=0
*/
private static Status setns(Target dst, int dstIndex, Status status) {
boolean condition = !status.isSignFlag();
int value = condition ? 1 : 0;
dst.set(dstIndex, value);
return status;
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SeteInstruction extends SetccInstruction {
public SeteInstruction() {
super("sete");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetgInstruction extends SetccInstruction {
public SetgInstruction() {
super("setg");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetgeInstruction extends SetccInstruction {
public SetgeInstruction() {
super("setge");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetlInstruction extends SetccInstruction {
public SetlInstruction() {
super("setl");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetleInstruction extends SetccInstruction {
public SetleInstruction() {
super("setle");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetnaInstruction extends SetccInstruction {
public SetnaInstruction() {
super("setna");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetnaeInstruction extends SetccInstruction {
public SetnaeInstruction() {
super("setnae");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetnbInstruction extends SetccInstruction {
public SetnbInstruction() {
super("setnb");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetnbeInstruction extends SetccInstruction {
public SetnbeInstruction() {
super("setnbe");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetncInstruction extends SetccInstruction {
public SetncInstruction() {
super("setnc");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetneInstruction extends SetccInstruction {
public SetneInstruction() {
super("setne");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetngInstruction extends SetccInstruction {
public SetngInstruction() {
super("setng");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetngeInstruction extends SetccInstruction {
public SetngeInstruction() {
super("setnge");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetnlInstruction extends SetccInstruction {
public SetnlInstruction() {
super("setnl");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetnleInstruction extends SetccInstruction {
public SetnleInstruction() {
super("setnle");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetnoInstruction extends SetccInstruction {
public SetnoInstruction() {
super("setno");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetnsInstruction extends SetccInstruction {
public SetnsInstruction() {
super("setns");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetnzInstruction extends SetccInstruction {
public SetnzInstruction() {
super("setnz");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetoInstruction extends SetccInstruction {
public SetoInstruction() {
super("seto");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetsInstruction extends SetccInstruction {
public SetsInstruction() {
super("sets");
}
}

View File

@ -0,0 +1,11 @@
package net.simon987.server.assembly.instruction;
/**
* alias of SetccInstruction
*/
public class SetzInstruction extends SetccInstruction {
public SetzInstruction() {
super("setz");
}
}

View File

@ -13,6 +13,10 @@ public class ShlInstruction extends Instruction {
super("shl", OPCODE);
}
public ShlInstruction(String alias) {
super(alias, OPCODE);
}
@Override
public Status execute(Target dst, int dstIndex, Target src, int srcIndex, Status status) {

View File

@ -52,7 +52,7 @@ define("ace/mode/mar_rules", ["require", "exports", "module", "ace/lib/oop", "ac
},
{
token: 'keyword.operator.assembly',
regex: '\\b(?:call|ret|jmp|jnz|jg|jl|jge|jle|hwi|jz|js|jns|jc|jnc|jo|jno|ja|jna)\\b',
regex: '\\b(?:call|ret|jmp|jnz|jg|jl|jge|jle|hwi|jz|js|jns|jc|jnc|jo|jno|ja|jna|seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b',
caseInsensitive: true
},
{

View File

@ -275,6 +275,7 @@ function parseInstruction(line, result, currentLine) {
if (!parseDWInstruction(line, result, currentLine)) {
if (new RegExp('\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|mul|push|pop|div|xor|hwi|hwq|nop|neg|' +
'seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns|' +
'call|ret|jmp|jnz|jg|jl|jge|jle|int|jz|js|jns|brk|not|jc|jnc|ror|rol|sal|sar|jo|jno|inc|dec|rcl|xchg|rcr|pushf|popf|ja|jna)\\b').test(mnemonic.toLowerCase())) {
@ -333,7 +334,7 @@ function parseInstruction(line, result, currentLine) {
strO1 = line.substring(line.indexOf(mnemonic) + mnemonic.length).trim();
//Validate operand number
if (!new RegExp('\\b(?:push|mul|pop|div|neg|call|jnz|jg|jl|jge|jle|hwi|hwq|jz|js|jns|ret|jmp|not|jc|jnc|jo|jno|inc|dec|ja|jna)\\b').test(mnemonic.toLowerCase())) {
if (!new RegExp('\\b(?:push|mul|pop|div|neg|call|jnz|jg|jl|jge|jle|hwi|hwq|jz|js|jns|ret|jmp|not|jc|jnc|jo|jno|inc|dec|ja|jna|seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase())) {
result.annotations.push({
row: currentLine,
column: 0,
@ -353,6 +354,16 @@ function parseInstruction(line, result, currentLine) {
});
}
if (new RegExp('\\b(?:seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase())) {
if (getOperandType(strO1, result) === OPERAND_IMM) {
result.annotations.push({
row: currentLine,
column: 0,
text: "Invalid operand type: " + strO1,
type: "error"
});
}
}
} else {
//No operand

View File

@ -0,0 +1,54 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetaInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETA;
public SetaInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetaInstruction();
}
/**
* SETA, SETNBE Above, Not Below or Equal CF=0 AND ZF=0
*/
@Test
public void execution() {
status.setCarryFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setCarryFlag(false);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setCarryFlag(true);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetaeInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETAE;
public SetaeInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetaeInstruction();
}
/**
* SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0
*/
@Test
public void execution() {
status.setCarryFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetbInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETB;
public SetbInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetbInstruction();
}
/**
* SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1
*/
@Test
public void execution() {
status.setCarryFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,54 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetbeInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETBE;
public SetbeInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetbeInstruction();
}
/**
* SETBE, SETNA Below or Equal, Not Above CF=1 OR ZF=1
*/
@Test
public void execution() {
status.setCarryFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setCarryFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(false);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(true);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetcInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETB;
public SetcInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetcInstruction();
}
/**
* SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1
*/
@Test
public void execution() {
status.setCarryFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,70 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Operand;
import net.simon987.server.assembly.OperandType;
import net.simon987.server.assembly.exception.*;
import org.junit.Test;
import static org.junit.Assert.*;
import java.io.ByteArrayOutputStream;
public class SetccInstructionTest {
/**
* Since SETCC is not an actual valid mnemonic, encoding the SetccInstruction class should throw an exception
*/
@Test
public void throwsInvalidMnemonicException() {
SetccInstruction instruction = new SetccInstruction();
boolean hasThrown = false;
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Operand operand = new Operand(OperandType.MEMORY_REG16, 1);
instruction.encode(stream, operand, 0);
} catch (AssemblyException exception) {
if (exception instanceof InvalidMnemonicException) {
hasThrown = true;
}
}
assertTrue(hasThrown);
}
@Test
public void throwsIllegalOperandException() {
SetccInstruction instruction = new SetccInstruction();
boolean hasThrownForZeroOperands = false;
boolean oneOperandImmediatIsInvalid = false;
boolean hasThrownForTwoOperands = false;
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
instruction.encode(stream, 0);
} catch (AssemblyException exception) {
if (exception instanceof IllegalOperandException) {
hasThrownForZeroOperands = true;
}
}
try {
Operand o1 = new Operand(OperandType.MEMORY_REG16, 1);
Operand o2= new Operand(OperandType.MEMORY_REG16, 1);
instruction.encode(stream, o1, o2, 0);
} catch (AssemblyException exception) {
if (exception instanceof IllegalOperandException) {
hasThrownForTwoOperands = true;
}
}
Operand invalidOperand = new Operand(OperandType.IMMEDIATE16, 0);
oneOperandImmediatIsInvalid = !instruction.operandValid(invalidOperand);
assertTrue(hasThrownForZeroOperands);
assertTrue(hasThrownForTwoOperands);
assertTrue(oneOperandImmediatIsInvalid);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SeteInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETE;
public SeteInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SeteInstruction();
}
/**
* SETE, SETZ Equal, Zero ZF=1
*/
@Test
public void execution() {
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,64 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetgInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETG;
public SetgInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetgInstruction();
}
/**
* SETG, SETNLE Greater, Not Less or Equal SF=OF AND ZF=0
*/
@Test
public void execution() {
status.setSignFlag(false);
status.setOverflowFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(true);
status.setOverflowFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(false);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(true);
status.setOverflowFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(false);
status.setOverflowFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,54 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetgeInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETGE;
public SetgeInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetgeInstruction();
}
/**
* SETGE, SETNL Greater or Equal, Not Less SF=OF
*/
@Test
public void execution() {
status.setSignFlag(true);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(true);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(false);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(false);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
}
}

View File

@ -0,0 +1,54 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetlInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETL;
public SetlInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetlInstruction();
}
/**
* SETL, SETNGE Less, Not Greater or Equal SF<>OF
*/
@Test
public void execution() {
status.setSignFlag(true);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(true);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,62 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetleInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETLE;
public SetleInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetleInstruction();
}
/**
* SETL, SETNGE Less, Not Greater or Equal SF<>OF
*/
@Test
public void execution() {
status.setSignFlag(true);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(false);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(true);
status.setOverflowFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,54 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetnaInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETBE;
public SetnaInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetnaInstruction();
}
/**
* SETBE, SETNA Below or Equal, Not Above CF=1 OR ZF=1
*/
@Test
public void execution() {
status.setCarryFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setCarryFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(false);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(true);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetnaeInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETB;
public SetnaeInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetnaeInstruction();
}
/**
* SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1
*/
@Test
public void execution() {
status.setCarryFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetnbInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETAE;
public SetnbInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetnbInstruction();
}
/**
* SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0
*/
@Test
public void execution() {
status.setCarryFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,54 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetnbeInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETA;
public SetnbeInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetnbeInstruction();
}
/**
* SETA, SETNBE Above, Not Below or Equal CF=0 AND ZF=0
*/
@Test
public void execution() {
status.setCarryFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setCarryFlag(false);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setCarryFlag(true);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetncInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETAE;
public SetncInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetncInstruction();
}
/**
* SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0
*/
@Test
public void execution() {
status.setCarryFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setCarryFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetneInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETNE;
public SetneInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetneInstruction();
}
/**
* SETNE, SETNZ Not Equal, Not Zero ZF=0
*/
@Test
public void execution() {
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
}
}

View File

@ -0,0 +1,63 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetngInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETLE;
public SetngInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetngInstruction();
}
/**
* SETLE, SETNG Less or Equal, Not Greater SF<>OF OR ZF=1
*/
@Test
public void execution() {
status.setSignFlag(true);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(false);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(true);
status.setOverflowFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,54 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetngeInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETL;
public SetngeInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetngeInstruction();
}
/**
* SETL, SETNGE Less, Not Greater or Equal SF<>OF
*/
@Test
public void execution() {
status.setSignFlag(true);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(true);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,54 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetnlInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETGE;
public SetnlInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetnlInstruction();
}
/**
* SETGE, SETNL Greater or Equal, Not Less SF=OF
*/
@Test
public void execution() {
status.setSignFlag(true);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(true);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(false);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(false);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
}
}

View File

@ -0,0 +1,64 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetnleInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETG;
public SetnleInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetnleInstruction();
}
/**
* SETG, SETNLE Greater, Not Less or Equal SF=OF AND ZF=0
*/
@Test
public void execution() {
status.setSignFlag(false);
status.setOverflowFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(true);
status.setOverflowFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
status.setOverflowFlag(false);
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(true);
status.setOverflowFlag(false);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
status.setSignFlag(false);
status.setOverflowFlag(true);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetnoInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETNO;
public SetnoInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetnoInstruction();
}
/**
* SETNO No Overflow OF=0
*/
@Test
public void execution() {
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetnsInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETNS;
public SetnsInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetnsInstruction();
}
/**
* SETS No Sign SF=0
*/
@Test
public void execution() {
status.setSignFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetoInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETO;
public SetoInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetoInstruction();
}
/**
* SETO Overflow OF=1
*/
@Test
public void execution() {
status.setOverflowFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setOverflowFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetsInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETS;
public SetsInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetsInstruction();
}
/**
* SETS Sign SF=1
*/
@Test
public void execution() {
status.setSignFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setSignFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}

View File

@ -0,0 +1,42 @@
package net.simon987.server.assembly.instruction;
import net.simon987.server.assembly.Register;
import net.simon987.server.assembly.RegisterSet;
import net.simon987.server.assembly.Status;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetzInstructionTest {
private RegisterSet registers;
private Status status;
private SetccInstruction instruction;
private int SETCCOPCODE = SetccInstruction.SETE;
public SetzInstructionTest() {
registers = new RegisterSet();
registers.put(1, new Register("R"));
registers.clear();
status = new Status();
status.clear();
instruction = new SetzInstruction();
}
/**
* SETE, SETZ Equal, Zero ZF=1
*/
@Test
public void execution() {
status.setZeroFlag(true);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 1);
status.setZeroFlag(false);
instruction.execute(registers, 1, SETCCOPCODE, status);
assertEquals(registers.get(1), 0);
}
}