From ca1682c431d4ff051b56f6b5f77c49db2f756112 Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Tue, 27 Feb 2018 08:37:55 +0000 Subject: [PATCH] acpi: define helper functions for working with opcode groups --- .../device/acpi/aml/parser_opcode_table.go | 66 +++++++++++ .../acpi/aml/parser_opcode_table_test.go | 108 ++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 src/gopheros/device/acpi/aml/parser_opcode_table_test.go diff --git a/src/gopheros/device/acpi/aml/parser_opcode_table.go b/src/gopheros/device/acpi/aml/parser_opcode_table.go index 66e5ef2..c1c43f8 100644 --- a/src/gopheros/device/acpi/aml/parser_opcode_table.go +++ b/src/gopheros/device/acpi/aml/parser_opcode_table.go @@ -130,3 +130,69 @@ const ( // Sentinel value to indicate freed objects pOpIntFreedObject = uint16(0xff + 0xff) ) + +// pOpIsLocalArg returns true if this opcode represents any of the supported local +// function args 0 to 7. +func pOpIsLocalArg(op uint16) bool { + return op >= pOpLocal0 && op <= pOpLocal7 +} + +// pOpIsMethodArg returns true if this opcode represents any of the supported +// input function args 0 to 6. +func pOpIsMethodArg(op uint16) bool { + return op >= pOpArg0 && op <= pOpArg6 +} + +// pOpIsArg returns true if this opcode is either a local or a method arg. +func pOpIsArg(op uint16) bool { + return pOpIsLocalArg(op) || pOpIsMethodArg(op) +} + +// pOpIsType2 returns true if this is a Type2Opcode. +// +// Grammar: +// Type2Opcode := DefAcquire | DefAdd | DefAnd | DefBuffer | DefConcat | +// DefConcatRes | DefCondRefOf | DefCopyObject | DefDecrement | +// DefDerefOf | DefDivide | DefFindSetLeftBit | DefFindSetRightBit | +// DefFromBCD | DefIncrement | DefIndex | DefLAnd | DefLEqual | +// DefLGreater | DefLGreaterEqual | DefLLess | DefLLessEqual | DefMid | +// DefLNot | DefLNotEqual | DefLoadTable | DefLOr | DefMatch | DefMod | +// DefMultiply | DefNAnd | DefNOr | DefNot | DefObjectType | DefOr | +// DefPackage | DefVarPackage | DefRefOf | DefShiftLeft | DefShiftRight | +// DefSizeOf | DefStore | DefSubtract | DefTimer | DefToBCD | DefToBuffer | +// DefToDecimalString | DefToHexString | DefToInteger | DefToString | +// DefWait | DefXOr +func pOpIsType2(op uint16) bool { + switch op { + case pOpAcquire, pOpAdd, pOpAnd, pOpBuffer, pOpConcat, + pOpConcatRes, pOpCondRefOf, pOpCopyObject, pOpDecrement, + pOpDerefOf, pOpDivide, pOpFindSetLeftBit, pOpFindSetRightBit, + pOpFromBCD, pOpIncrement, pOpIndex, pOpLand, pOpLEqual, + pOpLGreater, pOpLLess, pOpMid, + pOpLnot, pOpLoadTable, pOpLor, pOpMatch, pOpMod, + pOpMultiply, pOpNand, pOpNor, pOpNot, pOpObjectType, pOpOr, + pOpPackage, pOpVarPackage, pOpRefOf, pOpShiftLeft, pOpShiftRight, + pOpSizeOf, pOpStore, pOpSubtract, pOpTimer, pOpToBCD, pOpToBuffer, + pOpToDecimalString, pOpToHexString, pOpToInteger, pOpToString, + pOpWait, pOpXor: + return true + default: + return false + } +} + +// pOpIsDataObject returns true if this opcode is part of a DataObject definition +// +// Grammar: +// DataObject := ComputationalData | DefPackage | DefVarPackage +// ComputationalData := ByteConst | WordConst | DWordConst | QWordConst | String | ConstObj | RevisionOp | DefBuffer +// ConstObj := ZeroOp | OneOp | OnesOp +func pOpIsDataObject(op uint16) bool { + switch op { + case pOpBytePrefix, pOpWordPrefix, pOpDwordPrefix, pOpQwordPrefix, pOpStringPrefix, + pOpZero, pOpOne, pOpOnes, pOpRevision, pOpBuffer, pOpPackage, pOpVarPackage: + return true + default: + return false + } +} diff --git a/src/gopheros/device/acpi/aml/parser_opcode_table_test.go b/src/gopheros/device/acpi/aml/parser_opcode_table_test.go new file mode 100644 index 0000000..faa1c00 --- /dev/null +++ b/src/gopheros/device/acpi/aml/parser_opcode_table_test.go @@ -0,0 +1,108 @@ +package aml + +import "testing" + +func TestOpcodeIsX(t *testing.T) { + specs := []struct { + op uint16 + testFn func(uint16) bool + want bool + }{ + // OpIsLocalArg + {pOpLocal0, pOpIsLocalArg, true}, + {pOpLocal1, pOpIsLocalArg, true}, + {pOpLocal2, pOpIsLocalArg, true}, + {pOpLocal3, pOpIsLocalArg, true}, + {pOpLocal4, pOpIsLocalArg, true}, + {pOpLocal5, pOpIsLocalArg, true}, + {pOpLocal6, pOpIsLocalArg, true}, + {pOpLocal7, pOpIsLocalArg, true}, + {pOpArg0, pOpIsLocalArg, false}, + {pOpDivide, pOpIsLocalArg, false}, + // OpIsMethodArg + {pOpArg0, pOpIsMethodArg, true}, + {pOpArg1, pOpIsMethodArg, true}, + {pOpArg2, pOpIsMethodArg, true}, + {pOpArg3, pOpIsMethodArg, true}, + {pOpArg4, pOpIsMethodArg, true}, + {pOpArg5, pOpIsMethodArg, true}, + {pOpArg6, pOpIsMethodArg, true}, + {pOpLocal7, pOpIsMethodArg, false}, + {pOpIf, pOpIsMethodArg, false}, + // OpIsArg + {pOpLocal5, pOpIsArg, true}, + {pOpArg1, pOpIsArg, true}, + {pOpDivide, pOpIsArg, false}, + // OpIsType2 + {pOpAcquire, pOpIsType2, true}, + {pOpAdd, pOpIsType2, true}, + {pOpAnd, pOpIsType2, true}, + {pOpBuffer, pOpIsType2, true}, + {pOpConcat, pOpIsType2, true}, + {pOpConcatRes, pOpIsType2, true}, + {pOpCondRefOf, pOpIsType2, true}, + {pOpCopyObject, pOpIsType2, true}, + {pOpDecrement, pOpIsType2, true}, + {pOpDerefOf, pOpIsType2, true}, + {pOpDivide, pOpIsType2, true}, + {pOpFindSetLeftBit, pOpIsType2, true}, + {pOpFindSetRightBit, pOpIsType2, true}, + {pOpFromBCD, pOpIsType2, true}, + {pOpIncrement, pOpIsType2, true}, + {pOpIndex, pOpIsType2, true}, + {pOpLand, pOpIsType2, true}, + {pOpLEqual, pOpIsType2, true}, + {pOpLGreater, pOpIsType2, true}, + {pOpLLess, pOpIsType2, true}, + {pOpMid, pOpIsType2, true}, + {pOpLnot, pOpIsType2, true}, + {pOpLoadTable, pOpIsType2, true}, + {pOpLor, pOpIsType2, true}, + {pOpMatch, pOpIsType2, true}, + {pOpMod, pOpIsType2, true}, + {pOpMultiply, pOpIsType2, true}, + {pOpNand, pOpIsType2, true}, + {pOpNor, pOpIsType2, true}, + {pOpNot, pOpIsType2, true}, + {pOpObjectType, pOpIsType2, true}, + {pOpOr, pOpIsType2, true}, + {pOpPackage, pOpIsType2, true}, + {pOpVarPackage, pOpIsType2, true}, + {pOpRefOf, pOpIsType2, true}, + {pOpShiftLeft, pOpIsType2, true}, + {pOpShiftRight, pOpIsType2, true}, + {pOpSizeOf, pOpIsType2, true}, + {pOpStore, pOpIsType2, true}, + {pOpSubtract, pOpIsType2, true}, + {pOpTimer, pOpIsType2, true}, + {pOpToBCD, pOpIsType2, true}, + {pOpToBuffer, pOpIsType2, true}, + {pOpToDecimalString, pOpIsType2, true}, + {pOpToHexString, pOpIsType2, true}, + {pOpToInteger, pOpIsType2, true}, + {pOpToString, pOpIsType2, true}, + {pOpWait, pOpIsType2, true}, + {pOpXor, pOpIsType2, true}, + {pOpBytePrefix, pOpIsType2, false}, + // OpIsDataObject + {pOpBytePrefix, pOpIsDataObject, true}, + {pOpWordPrefix, pOpIsDataObject, true}, + {pOpDwordPrefix, pOpIsDataObject, true}, + {pOpQwordPrefix, pOpIsDataObject, true}, + {pOpStringPrefix, pOpIsDataObject, true}, + {pOpZero, pOpIsDataObject, true}, + {pOpOne, pOpIsDataObject, true}, + {pOpOnes, pOpIsDataObject, true}, + {pOpRevision, pOpIsDataObject, true}, + {pOpBuffer, pOpIsDataObject, true}, + {pOpPackage, pOpIsDataObject, true}, + {pOpVarPackage, pOpIsDataObject, true}, + {pOpLor, pOpIsDataObject, false}, + } + + for specIndex, spec := range specs { + if got := spec.testFn(spec.op); got != spec.want { + t.Errorf("[spec %d] opcode %q: expected to get %t; got %t", specIndex, spec.op, spec.want, got) + } + } +}