Skip to content
This repository has been archived by the owner on Apr 29, 2021. It is now read-only.

Commit

Permalink
Merge branch 'master' into armv4t_asm
Browse files Browse the repository at this point in the history
  • Loading branch information
matanlurey committed Jun 11, 2017
2 parents d2d62fd + 0061358 commit 0e49555
Show file tree
Hide file tree
Showing 50 changed files with 882 additions and 356 deletions.
32 changes: 31 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
# Use the default dart configuration.
language: dart
sudo: false
dart:
- dev
- stable

# Avoid re-downloading packages across different builds if possible.
cache:
directories:
- $HOME/.pub-cache
script: ./tool/travis.sh

# Check for analysis issues, run the test cases, and ensure `dartfmt` is run.
dart_task:
- dartanalyzer
- pub run test -p vm
- dartfmt

# If we're successful this far, then report coverage information to coveralls.
after_script: dart tool/coverage.dart

# The Dart language is constantly being worked on, and sometimes the dev and
# stable builds don't agree on what is considered formatted or what is analysis
# warning free (though this does not effect _using_ the library, likely).
#
# * We exclude `dev` from formatting checks.
# * We allow failures on `dev` for tests and the analyzer.
matrix:
allow_failures:
- dart: dev
dart_task: dartanalyzer
- dart: dev
dart_task: pub run test -p vm
exclude:
- dart: dev
dart_task: dartfmt
- dart: dev
dart_task: dartanalyzer
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# arm7_tdmi

[![Build Status](https://travis-ci.org/matanlurey/arm7_tdmi.svg?branch=master)](https://travis-ci.org/matanlurey/arm7_tdmi)
[![Coverage Status](https://coveralls.io/repos/github/matanlurey/arm7_tdmi/badge.svg)](https://coveralls.io/github/matanlurey/arm7_tdmi)

An emulator for the ARM7/TDMI processor.

Expand Down
41 changes: 34 additions & 7 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,27 +1,54 @@
analyzer:
strong-mode: true
strong-mode:
implicit-casts: false
implicit-dynamic: false

linter:
rules:
# Errors
# Error Rules
- avoid_empty_else
- comment_references
- control_flow_in_finally
- empty_statements
- hash_and_equals
- invariant_booleans
- iterable_contains_unrelated_type
- list_remove_unrelated_type
- no_adjacent_strings_in_list
- no_duplicate_case_values
- test_types_in_equals
- throw_in_finally
- unrelated_type_equality_checks
- valid_regexps

# Style
# Style Rules
- annotate_overrides
- avoid_init_to_null
- avoid_return_types_on_setters
- await_only_futures
- camel_case_types
- comment_references
- cascade_invocations
- constant_identifier_names
- directives_ordering
- empty_catches
- empty_constructor_bodies
- hash_and_equals
- implementation_imports
- library_names
- library_prefixes
- non_constant_identifier_names
- omit_local_variable_types
- only_throw_errors
- prefer_adjacent_string_concatenation
- prefer_collection_literals
- prefer_const_constructors
- prefer_contains
- prefer_final_fields
- prefer_final_locals
- prefer_initializing_formals
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- recursive_getters
- slash_for_doc_comments
- type_init_formals
- unrelated_type_equality_checks
- unnecessary_brace_in_string_interps
- unnecessary_this
2 changes: 1 addition & 1 deletion lib/arm7_tdmi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export 'src/thumb/decoder.dart' show ThumbDecoder;
export 'src/cpu.dart' show Cpu;
export 'src/debug.dart' show Trace, TracedCpu;
export 'src/device.dart' show Device;
export 'src/exceptions.dart' show ArmException;
export 'src/exceptions.dart' show ArmException, MemoryException;
export 'src/memory.dart' show Memory, ReadableMemory, WritableMemory;
export 'src/registers.dart' show Mode, Psr, Registers;
export 'src/vm.dart' show VM;
142 changes: 92 additions & 50 deletions lib/src/arm/addressing_modes/addressing_mode_1.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,32 +60,42 @@ typedef ShifterValues Immediate32Shifter(Cpu cpu, {int rotate, int immediate});
/// These auxiliary values are stored directly on the [Cpu]. Shifters can be
/// called directly or lazily after being decoded from an ARM instruction.
abstract class AddressingMode1 {
// ignore: constant_identifier_names
static const LSL_IMM = 0x0;
// ignore: constant_identifier_names
static const REGISTER = 0x0;
// ignore: constant_identifier_names
static const LSL_REG = 0x1;
// ignore: constant_identifier_names
static const LSR_IMM = 0x2;
// ignore: constant_identifier_names
static const LSR_REG = 0x3;
// ignore: constant_identifier_names
static const ASR_IMM = 0x4;
// ignore: constant_identifier_names
static const ASR_REG = 0x5;
// Rotate-right with extend (RRX) is also identified by 0x6. There is no
// collision because these share the same implementation.
// ignore: constant_identifier_names
static const ROR_IMM = 0x6;
// ignore: constant_identifier_names
static const ROR_REG = 0x7;
// ignore: constant_identifier_names
static const RRX = 0x06;

static const _registerShifters = const <int, dynamic>{
static const _registerShifters = const <int, Function>{
REGISTER: register,
LSL_REG: LSLRegister,
LSR_REG: LSRRegister,
ASR_REG: ASRRegister,
ROR_REG: RORRegister,
LSL_REG: logicalShiftLeftByRegister,
LSR_REG: logicalShiftRightByRegister,
ASR_REG: shiftRightByRegister,
ROR_REG: rotateRightByRegister,
};

static const _immediateShifters = const <int, dynamic>{
LSL_IMM: LSLImmediate,
LSR_IMM: LSRImmediate,
ASR_IMM: ASRImmediate,
ROR_IMM: RORImmediate,
static const _immediateShifters = const <int, Function>{
LSL_IMM: logicalShiftLeftByImmediate,
LSR_IMM: logicalShiftRightByImmediate,
ASR_IMM: shiftRightByImmediate,
ROR_IMM: rotateRightByImmediate,
};

/// Decodes the [Shifter] encoded by [shifterBits].
Expand All @@ -94,34 +104,42 @@ abstract class AddressingMode1 {
/// rotated.
static Shifter decodeShifter(int shifterBits, bool isImmediate32) {
if (isImmediate32) {
var encoding = new _Immediate32ShifterEncoding(shifterBits);
final encoding = new _Immediate32ShifterEncoding(shifterBits);
return (Cpu cpu) => immediate(cpu,
rotate: encoding.rotate, immediate: encoding.immediate);
}

int shifterCode = bitRange(shifterBits, 6, 4);
final shifterCode = bitRange(shifterBits, 6, 4);

/// Whether [shifterBits] is an [_ImmediateShifterEncoding].
bool isImmediate = isClear(shifterBits, 4);
final isImmediate = isClear(shifterBits, 4);

/// Whether [shifterBits] is an [_RegisterShifterEncoding].
bool isRegister = isClear(shifterBits, 7) && isSet(shifterBits, 4);
final isRegister = isClear(shifterBits, 7) && isSet(shifterBits, 4);

if (isImmediate) {
var shifter = _immediateShifters[shifterCode];
final shifter = _immediateShifters[shifterCode];
if (shifter == null) {
throw new UnsupportedError('$shifterBits');
}
var encoding = new _ImmediateShifterEncoding(shifterBits);
return (Cpu cpu) => shifter(cpu, shift: encoding.shift, rm: encoding.rm);
final encoding = new _ImmediateShifterEncoding(shifterBits);
return (Cpu cpu) => shifter(
cpu,
shift: encoding.shift,
rm: encoding.rm,
) as ShifterValues;
} else {
assert(isRegister);
var shifter = _registerShifters[shifterCode];
final shifter = _registerShifters[shifterCode];
if (shifter == null) {
throw new UnsupportedError('$shifterBits');
}
var encoding = new _RegisterShifterEncoding(shifterBits);
return (Cpu cpu) => shifter(cpu, rs: encoding.rs, rm: encoding.rm);
final encoding = new _RegisterShifterEncoding(shifterBits);
return (Cpu cpu) => shifter(
cpu,
rs: encoding.rs,
rm: encoding.rm,
) as ShifterValues;
}
}

Expand Down Expand Up @@ -153,9 +171,12 @@ abstract class AddressingMode1 {
/// Logical shift left by immediate.
///
/// See [_ImmediateShifterEncoding] for parameter documentation.
static ShifterValues LSLImmediate(Cpu cpu,
{@required int shift, @required int rm}) {
var gprs = cpu.gprs;
static ShifterValues logicalShiftLeftByImmediate(
Cpu cpu, {
@required int shift,
@required int rm,
}) {
final gprs = cpu.gprs;
int operand;
bool carryOut;

Expand All @@ -174,13 +195,16 @@ abstract class AddressingMode1 {
/// Logical shift left by register.
///
/// See [_RegisterShifterEncoding] for parameter documentation.
static ShifterValues LSLRegister(Cpu cpu,
{@required int rs, @required int rm}) {
var gprs = cpu.gprs;
static ShifterValues logicalShiftLeftByRegister(
Cpu cpu, {
@required int rs,
@required int rm,
}) {
final gprs = cpu.gprs;
int operand;
bool carryOut;

int shift = bitRange(gprs[rs], 7, 0);
final shift = bitRange(gprs[rs], 7, 0);
if (shift == 0) {
operand = gprs[rm];
carryOut = cpu.cpsr.c;
Expand All @@ -202,9 +226,12 @@ abstract class AddressingMode1 {
/// Logical shift right by immediate.
///
/// See [_ImmediateShifterEncoding] for parameter documentation.
static ShifterValues LSRImmediate(Cpu cpu,
{@required int shift, @required int rm}) {
var gprs = cpu.gprs;
static ShifterValues logicalShiftRightByImmediate(
Cpu cpu, {
@required int shift,
@required int rm,
}) {
final gprs = cpu.gprs;
int operand;
bool carryOut;

Expand All @@ -230,13 +257,16 @@ abstract class AddressingMode1 {
/// zero.
///
/// See [_RegisterShifterEncoding] for parameter documentation.
static ShifterValues LSRRegister(Cpu cpu,
{@required int rs, @required int rm}) {
var gprs = cpu.gprs;
static ShifterValues logicalShiftRightByRegister(
Cpu cpu, {
@required int rs,
@required int rm,
}) {
final gprs = cpu.gprs;
int operand;
bool carryOut;

int shift = bitRange(gprs[rs], 7, 0);
final shift = bitRange(gprs[rs], 7, 0);
if (shift == 0) {
operand = gprs[rm];
carryOut = cpu.cpsr.c;
Expand All @@ -257,9 +287,12 @@ abstract class AddressingMode1 {
/// Arithmetic shift right by immediate.
///
/// See [_ImmediateShifterEncoding] for parameter documentation.
static ShifterValues ASRImmediate(Cpu cpu,
{@required int shift, @required int rm}) {
var gprs = cpu.gprs;
static ShifterValues shiftRightByImmediate(
Cpu cpu, {
@required int shift,
@required int rm,
}) {
final gprs = cpu.gprs;
int operand;
bool carryOut;

Expand All @@ -282,13 +315,16 @@ abstract class AddressingMode1 {
/// Arithmetic shift right by register.
///
/// See [_RegisterShifterEncoding] for parameter documentation.
static ShifterValues ASRRegister(Cpu cpu,
{@required int rs, @required int rm}) {
var gprs = cpu.gprs;
static ShifterValues shiftRightByRegister(
Cpu cpu, {
@required int rs,
@required int rm,
}) {
final gprs = cpu.gprs;
int operand;
bool carryOut;

int shift = bitRange(gprs[rs], 7, 0);
final shift = bitRange(gprs[rs], 7, 0);
if (shift == 0) {
operand = gprs[rm];
carryOut = cpu.cpsr.c;
Expand All @@ -307,15 +343,18 @@ abstract class AddressingMode1 {
/// Rotate right by immediate.
///
/// See [_ImmediateShifterEncoding] for parameter documentation.
static ShifterValues RORImmediate(Cpu cpu,
{@required int shift, @required int rm}) {
var gprs = cpu.gprs;
static ShifterValues rotateRightByImmediate(
Cpu cpu, {
@required int shift,
@required int rm,
}) {
final gprs = cpu.gprs;
int operand;
bool carryOut;

if (shift == 0) {
// RRX
int c = cpu.cpsr.c ? 1 : 0;
final c = cpu.cpsr.c ? 1 : 0;
operand = (c << 31) | (gprs[rm] >> 1);
carryOut = isClear(gprs[rm], 0);
} else {
Expand All @@ -330,14 +369,17 @@ abstract class AddressingMode1 {
/// Rotate right by register.
///
/// See [_RegisterShifterEncoding] for parameter documentation.
static ShifterValues RORRegister(Cpu cpu,
{@required int rs, @required int rm}) {
var gprs = cpu.gprs;
static ShifterValues rotateRightByRegister(
Cpu cpu, {
@required int rs,
@required int rm,
}) {
final gprs = cpu.gprs;
int operand;
bool carryOut;

int shift = bitRange(gprs[rs], 7, 0);
int shiftLSB = bitRange(gprs[rs], 4, 0); // + 1 bit.
final shift = bitRange(gprs[rs], 7, 0);
final shiftLSB = bitRange(gprs[rs], 4, 0); // + 1 bit.

if (shift == 0) {
operand = gprs[rm];
Expand Down

0 comments on commit 0e49555

Please sign in to comment.