LyoKICogKEMpIENvcHlyaWdodCAyMDA5CiAqIEdyYWVtZSBSdXNzLCBncmFlbWUucnVzc0BnbWFpbC5jb20KICoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZS4KICoKICogU2VlIGZpbGUgQ1JFRElUUyBmb3IgbGlzdCBvZiBwZW9wbGUgd2hvIGNvbnRyaWJ1dGVkIHRvIHRoaXMKICogcHJvamVjdC4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgogKiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwKICogTUEgMDIxMTEtMTMwNyBVU0EKICovCgovKgogKiBUaGlzIGZpbGUgcHJvdmlkZXMgdGhlIGludGVycnVwdCBoYW5kbGluZyBmdW5jdGlvbmFsaXR5IGZvciBzeXN0ZW1zCiAqIGJhc2VkIG9uIHRoZSBzdGFuZGFyZCBQQy9BVCBhcmNoaXRlY3R1cmUgdXNpbmcgdHdvIGNhc2NhZGVkIGk4MjU5CiAqIFByb2dyYW1tYWJsZSBJbnRlcnJ1cHQgQ29udHJvbGxlcnMuCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vaTgyNTkuaD4KI2luY2x1ZGUgPGFzbS9pYm1wYy5oPgojaW5jbHVkZSA8YXNtL2ludGVycnVwdC5oPgoKI2lmIENPTkZJR19TWVNfTlVNX0lSUVMgIT0gMTYKI2Vycm9yICJDT05GSUdfU1lTX05VTV9JUlFTIG11c3QgZXF1YWwgMTYgaWYgQ09ORklHX1NZU19OVU1fSVJRUyBpcyBkZWZpbmVkIgojZW5kaWYKCkRFQ0xBUkVfSU5URVJSVVBUKDApOwpERUNMQVJFX0lOVEVSUlVQVCgxKTsKREVDTEFSRV9JTlRFUlJVUFQoMyk7CkRFQ0xBUkVfSU5URVJSVVBUKDQpOwpERUNMQVJFX0lOVEVSUlVQVCg1KTsKREVDTEFSRV9JTlRFUlJVUFQoNik7CkRFQ0xBUkVfSU5URVJSVVBUKDcpOwpERUNMQVJFX0lOVEVSUlVQVCg4KTsKREVDTEFSRV9JTlRFUlJVUFQoOSk7CkRFQ0xBUkVfSU5URVJSVVBUKDEwKTsKREVDTEFSRV9JTlRFUlJVUFQoMTEpOwpERUNMQVJFX0lOVEVSUlVQVCgxMik7CkRFQ0xBUkVfSU5URVJSVVBUKDEzKTsKREVDTEFSRV9JTlRFUlJVUFQoMTQpOwpERUNMQVJFX0lOVEVSUlVQVCgxNSk7CgppbnQgaW50ZXJydXB0X2luaXQodm9pZCkKewoJdTggaTsKCglkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkvKiBTZXR1cCBpbnRlcnJ1cHRzICovCglzZXRfdmVjdG9yKDB4MjAsIGlycV8wKTsKCXNldF92ZWN0b3IoMHgyMSwgaXJxXzEpOwoJc2V0X3ZlY3RvcigweDIzLCBpcnFfMyk7CglzZXRfdmVjdG9yKDB4MjQsIGlycV80KTsKCXNldF92ZWN0b3IoMHgyNSwgaXJxXzUpOwoJc2V0X3ZlY3RvcigweDI2LCBpcnFfNik7CglzZXRfdmVjdG9yKDB4MjcsIGlycV83KTsKCXNldF92ZWN0b3IoMHgyOCwgaXJxXzgpOwoJc2V0X3ZlY3RvcigweDI5LCBpcnFfOSk7CglzZXRfdmVjdG9yKDB4MmEsIGlycV8xMCk7CglzZXRfdmVjdG9yKDB4MmIsIGlycV8xMSk7CglzZXRfdmVjdG9yKDB4MmMsIGlycV8xMik7CglzZXRfdmVjdG9yKDB4MmQsIGlycV8xMyk7CglzZXRfdmVjdG9yKDB4MmUsIGlycV8xNCk7CglzZXRfdmVjdG9yKDB4MmYsIGlycV8xNSk7CgoJLyogTWFzayBhbGwgaW50ZXJydXB0cyAqLwoJb3V0YigweGZmLCBNQVNURVJfUElDICsgSU1SKTsKCW91dGIoMHhmZiwgU0xBVkVfUElDICsgSU1SKTsKCgkvKiBNYXN0ZXIgUElDICovCgkvKiBQbGFjZSBtYXN0ZXIgUElDIGludGVycnVwdHMgYXQgSU5UMjAgKi8KCS8qIElDVzMsIE9uZSBzbGF2ZSBQSUMgaXMgcHJlc2VudCAqLwoJb3V0YihJQ1cxX1NFTHxJQ1cxX0VJQ1c0LCBNQVNURVJfUElDICsgSUNXMSk7CglvdXRiKDB4MjAsIE1BU1RFUl9QSUMgKyBJQ1cyKTsKCW91dGIoSVIyLCBNQVNURVJfUElDICsgSUNXMyk7CglvdXRiKElDVzRfUE0sIE1BU1RFUl9QSUMgKyBJQ1c0KTsKCglmb3IgKGkgPSAwOyBpIDwgODsgaSsrKQoJCW91dGIoT0NXMl9TRU9JIHwgaSwgTUFTVEVSX1BJQyArIE9DVzIpOwoKCS8qIFNsYXZlIFBJQyAqLwoJLyogUGxhY2Ugc2xhdmUgUElDIGludGVycnVwdHMgYXQgSU5UMjggKi8KCS8qIFNsYXZlIElEICovCglvdXRiKElDVzFfU0VMfElDVzFfRUlDVzQsIFNMQVZFX1BJQyArIElDVzEpOwoJb3V0YigweDI4LCBTTEFWRV9QSUMgKyBJQ1cyKTsKCW91dGIoMHgwMiwgU0xBVkVfUElDICsgSUNXMyk7CglvdXRiKElDVzRfUE0sIFNMQVZFX1BJQyArIElDVzQpOwoKCWZvciAoaSA9IDA7IGkgPCA4OyBpKyspCgkJb3V0YihPQ1cyX1NFT0kgfCBpLCBTTEFWRV9QSUMgKyBPQ1cyKTsKCgkvKgoJICogRW5hYmxlIGNhc2NhZGVkIGludGVycnVwdHMgYnkgdW5tYXNraW5nIHRoZSBjYXNjYWRlIElSUSBwaW4gb2YKCSAqIHRoZSBtYXN0ZXIgUElDCgkgKi8KCXVubWFza19pcnEgKDIpOwoKCWVuYWJsZV9pbnRlcnJ1cHRzKCk7CgoJcmV0dXJuIDA7Cn0KCnZvaWQgbWFza19pcnEoaW50IGlycSkKewoJaW50IGltcl9wb3J0OwoKCWlmIChpcnEgPj0gQ09ORklHX1NZU19OVU1fSVJRUykKCQlyZXR1cm47CgoJaWYgKGlycSA+IDcpCgkJaW1yX3BvcnQgPSBTTEFWRV9QSUMgKyBJTVI7CgllbHNlCgkJaW1yX3BvcnQgPSBNQVNURVJfUElDICsgSU1SOwoKCW91dGIoaW5iKGltcl9wb3J0KSB8ICgxIDw8IChpcnEgJiA3KSksIGltcl9wb3J0KTsKfQoKdm9pZCB1bm1hc2tfaXJxKGludCBpcnEpCnsKCWludCBpbXJfcG9ydDsKCglpZiAoaXJxID49IENPTkZJR19TWVNfTlVNX0lSUVMpCgkJcmV0dXJuOwoKCWlmIChpcnEgPiA3KQoJCWltcl9wb3J0ID0gU0xBVkVfUElDICsgSU1SOwoJZWxzZQoJCWltcl9wb3J0ID0gTUFTVEVSX1BJQyArIElNUjsKCglvdXRiKGluYihpbXJfcG9ydCkgJiB+KDEgPDwgKGlycSAmIDcpKSwgaW1yX3BvcnQpOwp9Cgp2b2lkIHNwZWNpZmljX2VvaShpbnQgaXJxKQp7CglpZiAoaXJxID49IENPTkZJR19TWVNfTlVNX0lSUVMpCgkJcmV0dXJuOwoKCWlmIChpcnEgPiA3KSB7CgkJLyoKCQkgKiAgSVJRIGlzIG9uIHRoZSBzbGF2ZSAtIElzc3VlIGEgY29ycmVzcG9uZGluZyBFT0kgdG8gdGhlCgkJICogIHNsYXZlIFBJQyBhbmQgYW4gRU9JIGZvciBJUlEyICh0aGUgY2FzY2FkZSBpbnRlcnJ1cHQpCgkJICogIG9uIHRoZSBtYXN0ZXIgUElDCgkJICovCgkJb3V0YihPQ1cyX1NFT0kgfCAoaXJxICYgNyksIFNMQVZFX1BJQyArIE9DVzIpOwoJCWlycSA9IFNFT0lfSVIyOwoJfQoKCW91dGIoT0NXMl9TRU9JIHwgaXJxLCBNQVNURVJfUElDICsgT0NXMik7Cn0K